简体   繁体   English

linq to entites left outer join

[英]linq to entites left outer join

I am struggling linq to entities left outer join. 我正在努力向实体留下外连接。 I have two entities (tables): 我有两个实体(表):

Listings 
{
    ListingID,
    MakeID (nullable)
}

Makes
{
    MakeID,
    Description
}

I want to write something like this in LINQ: 我想在LINQ中写这样的东西:

select listings.listingID
,listings.makeid
, IsNull(makes.Description, 'NA')
from listings
left outer join makes
on listings.makeid = makes.makeid

Below is your solution to achieving a left join. 以下是实现左连接的解决方案。 In terms of other resources I really recommend trying out linq pad: http://www.linqpad.net/ It is a great learning tool for Linq. 在其他资源方面,我真的建议尝试使用linq pad: http//www.linqpad.net/这对Linq来说是一个很棒的学习工具。

// Listing class/container/table
public class Listing
{
    public string ListingID {get;set;}
    public Int32? MakeID {get;set;}
}

// Make class/container/table
public class Make
{
    public Int32 MakeID {get;set;}
    public string Description {get;set;}
}

public class Main
{
    public static void LinqMain()
    {
        // Populate the listing table with data
        List<Listing> listings = new List<Listing>()
        {
            new Listing() { ListingID = "Test 1", MakeID = 1 },
            new Listing() { ListingID = "Test 2", MakeID = 1 },
            new Listing() { ListingID = "No Make", MakeID = null },
            new Listing() { ListingID = "Test 3", MakeID = 3 },
            new Listing() { ListingID = "Another Makeless", MakeID = null }
        };

        // Populate the makes table with data
        List<Make> makes = new List<Make>()
        {
            new Make() { MakeID = 1, Description = "Make 1"},
            new Make() { MakeID = 2, Description = "Make 2"},
            new Make() { MakeID = 3, Description = "Make 3"},
            new Make() { MakeID = 4, Description = "Make 4"}
        };

        // Return the left join on Make Id
        var result = from l in listings

                     // These two lines are the left join. 
                     join leftm in makes on l.MakeID equals leftm.MakeID into leftm
                     from m in leftm.DefaultIfEmpty()

                     // To ensure the select does not get bogged down with too much logic use the let syntax
                     let description = m == null ? "NA" : m.Description

                     select new { l.ListingID, l.MakeID, description };


    }

The result variable would contain: 结果变量将包含:

  1. { ListingID = "Test 1", MakeID = 1, description = "Make 1" } {ListingID =“Test 1”,MakeID = 1,description =“Make 1”}
  2. { ListingID = "Test 2", MakeID = 1, description = "Make 1" } {ListingID =“Test 2”,MakeID = 1,description =“Make 1”}
  3. { ListingID = "No Make", MakeID = null, description = "NA" } {ListingID =“No Make”,MakeID = null,description =“NA”}
  4. { ListingID = "Test 3", MakeID = 3, description = "Make 3" } {ListingID =“Test 3”,MakeID = 3,description =“Make 3”}
  5. { ListingID = "Another Makeless", MakeID = null, description = "NA" } {ListingID =“Another Makeless”,MakeID = null,description =“NA”}

Anybody who tells you to use .DefaultIfEmpty() as part of an outer join in LINQ to Entities hasn't actually tried it themselves! 任何告诉你使用.DefaultIfEmpty()作为LINQ to Entities外连接的一部分的人实际上并没有尝试过它! Tt simply does not work - at least as at .NET 3.5 SP1. Tt根本不起作用 - 至少在.NET 3.5 SP1中是这样。

This blogger tells you how you should actually do it. 这位博主告诉你应该如何实际做到这一点。 Essentially, .NET does outer joins in LINQ to Entities by default , so you should leave out the .DefaultIfEmpty(). 本质上,.NET 默认情况下在LINQ to Entities中执行外连接,因此您应该省略.DefaultIfEmpty()。 For multiple outer joins you have to nest the query groups to keep their context clear. 对于多个外部联接,您必须嵌套查询组以保持其上下文清晰。

http://oddiandeveloper.blogspot.com/2008/12/testable-left-outer-join-in-linq-to.html http://oddiandeveloper.blogspot.com/2008/12/testable-left-outer-join-in-linq-to.html

This should help, it's a blog post I made a while ago, should still be relevant and might help with testability as well. 这应该有所帮助,这是我之前发表的一篇博文,应该仍然具有相关性,也可能有助于测试性。

Also make sure your foreign keys are in place when you generate your entity model, it'll help setup your dependencies. 在生成实体模型时还要确保外键已到位,它将帮助您设置依赖项。

Not infront of a dev machine to check, but something like this perhaps? 不要在开发机器前面检查,但这样的事情可能呢?

var x = from l in listings
    join m in makes on l.makeid equals m.makeid into g
    from ma in g.DefaultIfEmpty()
    select new 
    {
        l.listingID, 
        l.makeid, 
        (ma.Description == null ? "NA" : ma.Description)
    };

If you have any trouble with it, let me know and i'll check on my work pc. 如果您有任何问题,请告诉我,我会检查我的工作电脑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM