【发布时间】:2018-09-24 01:36:27
【问题描述】:
我需要帮助了解如何在 Linq-to-Entities 语句中执行多个连接。我总是很难理解 Linq 连接的表达式,尤其是多重连接。我总是最终使用子查询。例如:
public List<MyReportItem> GetReportItemsHelper(string[] years, string[] quarters, string[] areas, string myType, string[] ownerships, IEnumerable<String> fieldCodes)
{
var _reportItems = _db.MytableEntity1
.Where(c => c.FieldID.Equals(MY_ID) //Id Field
&& years.Contains(c.PeriodYear) //PeriodYear/Year
&& quarters.Contains(c.Period) //Period/Quarters
&& c.MyType.Equals(myType) //Special Type
&& areas.Contains(c.Area) //Area
&& ownerships.Contains(c.Ownership)) //Ownership
.Where(c => fieldCodes.Contains(c.FieldCode)) //Field Code
.Where(c => c.Suppress.Equals("0")) //Suppression is false
.Select(c => new MyReportItem
{
Field1 = c.FieldA,
Field2 = c.FieldB,
Field3 = c.FieldC.TrimEnd(),
//Sub-queries
Field4 = _db.MytableEntity2.Where(g => g.FieldID.Equals(c.FieldID) && g.MyType.Equals(c.MyType) && g.Area.Equals(c.Area)).Select(g => g.AreaName.TrimEnd()).FirstOrDefault(),
Field5 = _db.MytableEntity3.Where(o => o.Ownership.Equals(c.Ownership)).Select(o => o.OwnerTitle.TrimEnd()).FirstOrDefault(),
Field6 = _db.MytableEntity4.Where(i => c.FieldCode.Equals(i.FieldCode) && myType.Equals(c.MyType)).Select(i => i.FieldTitle).FirstOrDefault(),
Field7 = _db.MytableEntity4.Where(i => c.FieldCode.Equals(i.FieldCode) && myType.Equals(c.MyType)).Select(i => i.FieldLevel).FirstOrDefault(),
Field8 = c.FieldD,
Field9 = c.FieldE,
Field10 = c.FieldF,
Field11 = c.FieldG,
Field12 = c.FieldH,
Field13 = c.FieldI,
Field14 = c.FieldJ,
Field15 = c.FieldK
}).Distinct().ToList();
return _reportItems; //return report detail items
}
但现在我面临着一个非常大的数据库(可能有 6000 万条记录或更多?),并且子查询正在成为我们响应时间的瓶颈。我想解决这个问题并利用“加入”。我看到很多示例展示了如何执行连接,但我几乎看不到任何带有 multiple 连接的示例。
如何对“MytableEntity2”、“MytableEntity3”、“MytableEntity4”执行多个连接(在新的“MyReportItem”内),以消除字段 4-7 的子查询?如何将 4 个实体表组合成一个表达式?谢谢!
【问题讨论】:
-
请参阅stackoverflow.com/a/41274884/2557128,但请注意,通常在 EF 中您根本不需要使用连接,您应该在主对象上具有导航属性以拉入其他相关对象(表)。跨度>
-
@NetMage 你有例子吗?当我在选择之前进行连接时,它会破坏我的选择。具体来说, .Select(c => new MyReportItem { }) 不再按预期工作。你能展示一下它是如何工作的吗?
-
您能否更具体地了解“不再按预期工作”的意思?我看到您的子查询中有
FirstOrDefault,在Join中可能会有不同的处理方式。 -
您不需要更改数据库。如果您不想更改实体,则需要使用
Join。顺便说一句,请注意,您在MytableEntity4的子查询中对myType进行了冗余测试。
标签: c# join lambda entity-framework-6 linq-to-entities