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