LINQ - 左外连接 - 更好的方法

时间:2013-01-17 17:28:38

标签: linq-to-entities

我有两张表需要从...房间和地址获取数据。 Rooms表中有一个AddressID字段但它可以为null,因此关系为0到1.我一直在尝试编写一个LINQ语句,它将返回一个特定的Room和Address信息(如果存在)。我的模型定义如下:

public partial class Room
{
    public Room()
    {
        this.Address = new HashSet<Address>();
    }

    public int RoomID { get; set; }
    public Nullable<int> AddressID { get; set; }
    public string Comments { get; set; }
    public string Notes { get; set; }

    public virtual ICollection<Address> Address { get; set; }
}

我尝试在linq语句中使用.Include(“Address”),但它不起作用,我相信它是由Join语句引起的(我读过,一旦使用它,它会默默地删除Include)。

这是一个丑陋的方式,但我知道有更好的方法:

var csdDB = new CSDContext(CustomerCode);

IList<Room> rooms = (from r in csdDB.Rooms
                        join sr in csdDB.SiteRooms
                            on r.RoomID equals sr.RoomID
                        where sr.SiteID == id
                        orderby r.RoomName
                        select r).ToList<Room>();

int? addressID = rooms.FirstOrDefault<Room>().AddressID;

if (addressID != null)
{
    IList<Address> address = (from a in csdDB.Addresses
                                where a.AddressID == addressID
                                select a).ToList<Address>();

    rooms.FirstOrDefault<Room>().Address = address;
}

我尝试直接对结果进行过滤:

IList<Address> address = (from a in csdDB.Addresses
                            where a.AddressID == rooms.FirstOrDefault().AddressID
                            select a).ToList<Address>();

但它引发了一个错误:

Unable to create a constant value of type 'Models.CSD.Room'. Only primitive types or enumeration types are supported in this context.

对于如何使这种更干净/更好的任何建议表示赞赏!

1 个答案:

答案 0 :(得分:0)

在LINQ中加入左连接可能看起来像这样:

var results = (from r in csdDB.Rooms
               join sr in csdDB.SiteRooms
                   on r.RoomID equals sr.RoomID && sr.SiteID equals id
               join addr in csdDB.Addresses
                   on r.AddressID equals addr.AddressID into roomAddrs
               from roomAddr in roomAddrs.DefaultIfEmpty(new Address())
               select new 
               {
                   Room = r,
                   Address = roomAddr
               }