Join/Where with LINQ and Lambda
我在使用Linq和lambda编写的查询中遇到问题。到目前为止,我有很多错误,这是我的代码:
1 2 3 4 5 | 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查询语法更清晰、更自然,并且更容易发现错误:
1 2 3 4 5 6 | 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扩展方法:
1 2 3 4 5 6 7 | 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新手的话,这是非常宝贵的)和一个虚拟数据库构建了以下查询:
1 2 3 4 5 6 | Posts.Join( Post_metas, post => post.Post_id, meta => meta.Post_id, (post, meta) => new { Post = post, Meta = meta } ) |
或
1 2 3 | 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记录,那么可以执行以下操作:
1 2 | var post = Posts.Single(p => p.ID == 1); var metas = post.Post_metas.ToList(); |
如果您想避免n+1问题,那么可以显式地告诉Linq to SQL一次性加载所有相关项(尽管这可能是您更熟悉L2时的高级主题)。下面的示例说"当您加载一个日志时,还可以通过"post-metas"属性表示的外键加载与其关联的所有记录:
1 2 3 4 5 6 7 |
可以对同一类型或多个不同类型的一组
您的按键选择器不正确。它们应该获取相关表类型的对象,并返回要在联接中使用的键。我认为你的意思是:
1 2 3 4 | var query = database.Posts.Join(database.Post_Metas, post => post.ID, meta => meta.Post_ID, (post, meta) => new { Post = post, Meta = meta }); |
之后可以应用WHERE子句,而不是作为键选择器的一部分。
丹尼尔对语法关系有一个很好的解释,但是我把这个文档放在一起,以便我的团队能够更简单地理解它。希望能帮上忙
发布是因为当我启动Linq+EntityFramework时,我盯着这些示例看了一天。
如果您使用的是EntityFramework,并且在您的
1 2 3 4 |
如果你是先做代码,你就要设置这个属性:
1 2 3 4 5 6 | class Post { [Key] public int ID {get; set} public int MetaID { get; set; } public virtual Meta Meta {get; set;} } |
我做过这样的事;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | var certificationClass = _db.INDIVIDUALLICENSEs .Join(_db.INDLICENSECLAsses, IL => IL.LICENSE_CLASS, ILC => ILC.NAME, (IL, ILC) => new { INDIVIDUALLICENSE = IL, INDLICENSECLAsse = ILC }) .Where(o => o.INDIVIDUALLICENSE.GLOBALENTITYID =="ABC" && o.INDIVIDUALLICENSE.LICENSE_TYPE =="ABC") .Select(t => new { value = t.PSP_INDLICENSECLAsse.ID, name = t.PSP_INDIVIDUALLICENSE.LICENSE_CLASS, }) .OrderBy(x => x.name); |
可能有点像
1 2 3 | var myvar = from a in context.MyEntity join b in context.MyEntity2 on a.key equals b.key select new { prop1 = a.prop1, prop2= b.prop1}; |
1等于1两个不同的表联接
1 2 3 4 | var query = from post in database.Posts join meta in database.Post_Metas on 1 equals 1 where post.ID == id select new { Post = post, Meta = meta }; |
这个LINQ查询应该对您有效。它将得到所有有post meta的帖子。
1 2 3 4 | var query = database.Posts.Join(database.Post_Metas, post => post.postId, // Primary Key meta => meat.postId, // Foreign Key (post, meta) => new { Post = post, Meta = meta }); |
等效SQL查询
1 2 | Select * FROM Posts P INNER JOIN Post_Metas pm ON pm.postId=p.postId |