Linq to Entities 6,多对多关系,从两个表中选择字段到一个对象中

Linq to Entites 6, Many-to-many relationship, Selecting Fields from Both tables into an object

我花了一个下午的时间在 Whosebug 上,Google 寻找一种方法来使用 linq to entities 进行简单的 SQL 查询。我正在尝试从通过多对多关系连接的两个 table 中获取数据。在 SQL 我会这样写查询:

   SELECT v.[VendorID]
    , t.[UnitNumber]
    , t.[Name]
    , t.[Address]
    , t.[CityStateZip]
FROM [Tenant] t
INNER JOIN [TenantVendor] tv ON tv.[TenantID] = t.[TenantID]
INNER JOIN [Vendor] v on v.[VendorID] = tv.[VendorID]
WHERE t.[UnitNumber] LIKE '%100A%'
    AND t.[CompanyID] = 17874;

我在列表中有一个对象,我正在 select 将数据导入其中,看起来像这样直接应用于网格:

public class SearchObject
    {
        public int IDField { get; set; }
        public string UniqueField { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public string CityStateZip { get; set; }
    }

更重要的是,m2m table 仅由两个 table 的主键组成,因此它没有 select 的实体。它们作为一个集合显示在彼此的实体下(来自租户实体):

public virtual ICollection<Vendor> Vendors { get; set; }

我更喜欢 lambda 表达式,但查询也可以正常工作。我得到的最接近的是这两个:

SearchData = DBContext.Tenants
             .Where(t => t.Company.Name == CompanyName && t.UnitNumber.ToString().Contains(SearchText))                            
             .OrderBy(DynamicSort)
             .Skip(StartRow)
             .Take(PageSize)
             .Select(t => new SearchObject { IDField = t.Vendors, UniqueField = t.UnitNumber.ToString(), Name = t.Name, Address = t.Address, CityStateZip = t.CityStateZip })
             .ToList();

那个不行,因为t.Vendors是一个集合,我想要的只是vendorID。

这个有效,但是 returns 记录太多,因为它缺少两个 table 之间的连接:

SearchData = (from t in DBContext.Tenants
              from v in DBContext.Vendors
              where t.Company.Name == CompanyName && t.UnitNumber.ToString().Contains(SearchText) 
              select new SearchObject { IDField = v.VendorID , UniqueField = t.UnitNumber.ToString(), Name = t.Name, Address = t.Address, CityStateZip = t.CityStateZip })
              .ToList();

编辑/更新 在 ElMent 向我提供正确答案后,我想出了如何使用 C# 方法实现相同的结果,SelectMany 是关键。

SearchData = DBContext.Tenants
    .Where(t => t.Company.Name == CompanyName && t.UnitNumber.ToString().Contains(SearchText))
    .OrderBy(DynamicSort)
    .Skip(StartRow)
    .Take(PageSize)
    .SelectMany(t=>t.Vendors.Select(v => new SearchObject { IDField = v.VendorID, UniqueField = t.UnitNumber.ToString() + " - " + v.VendorNumber, Name = t.Name, Address = t.Address, CityStateZip = t.CityStateZip }))                                                                                                        
    .ToList();

这个呢。请参阅第二行的 "from v in t.Vendors"。

SearchData = (from t in DBContext.Tenants
                                 from v in t.Vendors
                                 where t.Company.Name == CompanyName && t.UnitNumber.ToString().Contains(SearchText) 
                                select new SearchObject { IDField = v.VendorID , UniqueField = t.UnitNumber.ToString(), Name = t.Name, Address = t.Address, CityStateZip = t.CityStateZip })
                                .ToList();

更多信息在这里: https://msdn.microsoft.com/en-us/library/bb386932(v=vs.110).aspx