如何摆脱多个左键在EF核心急切地加载相同桌子
我正在用急切的加载将Oracle SP转换为EFCORE,但我想知道如何更有效地转换以下查询。
我的主要目的是编码它更干净,并学习更好的方法。它导致为.include()创建许多MRC_BATCH_INFO实例,这不是我想要的。
SELECT C.COLL_ID,
MI.MRC_INC_NAME,
ME.MRC_EXC_NAME,
SI.STR_INC_NAME,
SE.STR_EXC_NAME,
AI.MSTR_INC_NAME,
AE.MSTR_EXC_NAME,
FROM MERCHANT C
,MRC_BATCH_INFO MI
,MRC_BATCH_INFO ME
,MRC_BATCH_INFO SI
,MRC_BATCH_INFO SE
,MRC_BATCH_INFO AI
,MRC_BATCH_INFO AE
WHERE C.COLL_ID = PI_COLL_ID
AND C.MRC_INC_LIST_ID = MI.COLL_MRC_BATCH_ID(+)
AND C.MRC_EXC_LIST_ID = ME.COLL_MRC_BATCH_ID(+)
AND C.STR_INC_LIST_ID = SI.COLL_MRC_BATCH_ID(+)
AND C.STR_EXC_LIST_ID = SE.COLL_MRC_BATCH_ID(+)
AND C.MSTR_INC_LIST_ID = AI.COLL_MRC_BATCH_ID(+)
AND C.MSTR_EXC_LIST_ID = AE.COLL_MRC_BATCH_ID(+)
作为
var result = await _mrcRepository
.Include(x=>x.MrcBatchInfo_MI) // I want to get rid of these LeftJ
.Include(x=>x.MrcBatchInfo_ME) // reduce it as one if it's possible
.Include(x=>x.MrcBatchInfo_SI) // or any other optimization
.Include(x=>x.MrcBatchInfo_SE)
.Include(x=>x.MrcBatchInfo_AI)
.Include(x=>x.MrcBatchInfo_AE)
.Where(x=>x.CollId==collId)
//.Select( ) in this part and its OK
.ToListAsync();
任何评论。
I'm converting Oracle Sp to EFCore with eager loading but I wonder that how to convert below query with more efficiently.
My main aim is code it more clean and learn a better way if it's possible. It's leads to create many MRC_BATCH_INFO instances for .Include() which is not I want.
SELECT C.COLL_ID,
MI.MRC_INC_NAME,
ME.MRC_EXC_NAME,
SI.STR_INC_NAME,
SE.STR_EXC_NAME,
AI.MSTR_INC_NAME,
AE.MSTR_EXC_NAME,
FROM MERCHANT C
,MRC_BATCH_INFO MI
,MRC_BATCH_INFO ME
,MRC_BATCH_INFO SI
,MRC_BATCH_INFO SE
,MRC_BATCH_INFO AI
,MRC_BATCH_INFO AE
WHERE C.COLL_ID = PI_COLL_ID
AND C.MRC_INC_LIST_ID = MI.COLL_MRC_BATCH_ID(+)
AND C.MRC_EXC_LIST_ID = ME.COLL_MRC_BATCH_ID(+)
AND C.STR_INC_LIST_ID = SI.COLL_MRC_BATCH_ID(+)
AND C.STR_EXC_LIST_ID = SE.COLL_MRC_BATCH_ID(+)
AND C.MSTR_INC_LIST_ID = AI.COLL_MRC_BATCH_ID(+)
AND C.MSTR_EXC_LIST_ID = AE.COLL_MRC_BATCH_ID(+)
as
var result = await _mrcRepository
.Include(x=>x.MrcBatchInfo_MI) // I want to get rid of these LeftJ
.Include(x=>x.MrcBatchInfo_ME) // reduce it as one if it's possible
.Include(x=>x.MrcBatchInfo_SI) // or any other optimization
.Include(x=>x.MrcBatchInfo_SE)
.Include(x=>x.MrcBatchInfo_AI)
.Include(x=>x.MrcBatchInfo_AE)
.Where(x=>x.CollId==collId)
//.Select( ) in this part and its OK
.ToListAsync();
Thx for any comment.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
包括
和选择
有不同的目的。include
在中导致
在查询中,而EF执行连接是不是,而是用于急切地加载相关数据时您想加载整个实体图。 (一个实体及其相关实体)选择
是处理称为投影的概念。在这些情况下,您不一定会返回实体,而是告诉EF使用其实体及其关系来填充所需的输出。因此,例如,如果您想要的数据是您的方法返回的东西,我们将创建一个Poco dto对象或ViewModel来保存所需的输出数据:
}
我们可以从这里构建
select> select
条款从商人实体图中加载DTO,EF可以通过导航属性来算出相关数据。这样做的优点是,所得的SQL只能从所需的相关表中撤回数据,而不是从商家和相关表中的所有数据。...使用更合适的命名约定,我猜想了要返回的姓名属性的详细信息。 EF仍然会产生连接和幕后类型,因此不要指望它可以模仿现有的查询,但是在大多数情况下,绩效明智的是EF生成的查询非常好。
可能有一些复杂的情况可以更明确地优化,在这种情况下,选项是将视图和映射实体映射到视图而不是基本表。 (适合复杂的阅读操作)
Include
andSelect
serve different purposes. WhileInclude
results inJOIN
in the queries, it is not required for EF to perform joins, instead it is used for Eager Loading related data when you want to load an entire entity graph. (An entity and it's related entities)Select
on the other hand is for handling a concept called Projection. In these cases you aren't necessarily returning entities, but rather telling EF to use it's entities and their relations to populate a desired output.So for example, if the data you want is something that your method would return, we would create a POCO DTO object or ViewModel to hold that desired output data:
}
From here we can build a
Select
clause to load a DTO from the merchant entity graph, and EF can work out the related data via navigation properties. The advantage of this is that the resulting SQL will only pull back the data from the relevant tables that it needs, rather than everything from the Merchant and related tables.... using more appropriate naming convention and I guessed at the details like Name property to be returned. EF will still generate Joins and such behind the scenes so don't expect it to mimic an existing query, but for the most part performance wise the queries that EF generates are pretty good.
There may be complex cases that can be optimized more explicitly in which case an option is to leverage Views and mapping entities to the view rather than the base tables. (good for complex read operations)
就我个人而言,我认为您的数据库设计倒退。
而不是将
商人
表带有6个外键的表。您需要一个具有FK到商人
的表格,以及一个类型列来表示6(或更多)类型。这要么在MRC_BATCH_INFO
表上,要么在新的多一对一的联接表上,具体取决于这两个表的相关方式。Personally, I think your database design is backwards.
Rather than having a
MERCHANT
table with 6 foreign keys to the same table. You need a table with a FK toMERCHANT
, and a type column to represent the 6 (or more) types. This would either be on theMRC_BATCH_INFO
table, or on a new many-to-many join table, depending on how these two tables are related.