C#加入/ Linq和Lambda

我在用Linq和Lambda编写的查询时遇到了麻烦。 到目前为止,我得到了很多错误,这里是我的代码:

int id = 1;
var query = database.Posts.Join(database.Post_Metas,
                                post => database.Posts.Where(x => x.ID == id),
                                meta => database.Post_Metas.Where(x => x.Post_ID == id),
                                (post, meta) => new { Post = post, Meta = meta });

我是使用Linq的新手,所以我不确定这个查询是否正确。


我发现,如果您熟悉SQL语法,那么使用LINQ查询语法会更清晰,更自然,并且更易于发现错误:

var id = 1;
var query =
   from post in database.Posts
   join meta in database.Post_Metas on post.ID equals meta.Post_ID
   where post.ID == id
   select new { Post = post, Meta = meta };

如果你真的坚持使用lambda表达式,你的语法是相当有限的。 以下是使用LINQ扩展方法的相同查询:

var id = 1;
var query = database.Posts    // your starting point - table in the "from" statement
   .Join(database.Post_Metas, // the source table of the inner join
      post => post.ID,        // Select the primary key (the first part of the "on" clause in an sql "join" statement)
      meta => meta.Post_ID,   // Select the foreign key (the second part of the "on" clause)
      (post, meta) => new { Post = post, Meta = meta }) // selection
   .Where(postAndMeta => postAndMeta.Post.ID == id);    // where statement

你可以用这两种方法。 使用LINQPad(如果您是LINQ的新手无价之宝)和一个虚拟数据库,我建立了以下查询:

Posts.Join(
    Post_metas,
    post => post.Post_id,
    meta => meta.Post_id,
    (post, meta) => new { Post = post, Meta = meta }
)

要么

from p in Posts
join pm in Post_metas on p.Post_id equals pm.Post_id
select new { Post = p, Meta = pm }

在这种特殊情况下,我认为LINQ语法更清晰(我在两者之间切换取决于哪一个最容易阅读)。

我想指出的一点是,如果数据库中有适当的外键(在post和post_meta之间),那么除非您尝试加载大量记录,否则您可能不需要显式连接。 你的例子似乎表明你正在尝试加载一个帖子,它是元数据。 假设每篇文章都有很多post_meta记录,那么您可以执行以下操作:

var post = Posts.Single(p => p.ID == 1);
var metas = post.Post_metas.ToList();

如果你想避免n + 1问题,那么你可以明确地告诉LINQ to SQL一次性加载所有相关的项目(尽管这可能是你更熟悉L2S的高级主题)。 下面的例子说:“当你加载一个Post时,还通过'Post_metas'属性代表的外键加载与它相关的所有记录:

var dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Post>(p => p.Post_metas);

var dataContext = new MyDataContext();
dataContext.LoadOptions = dataLoadOptions;

var post = Posts.Single(p => p.ID == 1); // Post_metas loaded automagically

可以在同一类型或多种不同类型的一组DataLoadOptions上进行多次LoadWith调用。 如果你这么做,你可能只想考虑缓存。


您的密钥选择器不正确。 他们应该使用有关表的类型的对象并返回用于连接的键。 我认为你的意思是:

var query = database.Posts.Join(database.Post_Metas,
                                post => post.ID,
                                meta => meta.Post_ID,
                                (post, meta) => new { Post = post, Meta = meta });

您可以在之后应用where子句,而不是作为键选择器的一部分。

链接地址: http://www.djcxy.com/p/75195.html

上一篇: C# Joins/Where with Linq and Lambda

下一篇: How can I measure the similarity between 2 strings?