C# EF是否自动加载多对多引用集合
假设我们有下面的db结构C# EF是否自动加载多对多引用集合,c#,entity-framework-5,cartesian-product,C#,Entity Framework 5,Cartesian Product,假设我们有下面的db结构 Organization { Guid OrganizationId //.... } User { Guid UserId } OrganizationUsers { Guid OrganizationId Guid UserId } 当edmx生成此类时,它将组织用户抽象为多对多引用。因此,不会为其生成POCO类 假设我从上下文加载数据,但为了避免笛卡尔式生成,我不使用include,而是进行
Organization
{
Guid OrganizationId
//....
}
User
{
Guid UserId
}
OrganizationUsers
{
Guid OrganizationId
Guid UserId
}
当edmx生成此类时,它将组织用户
抽象为多对多引用。因此,不会为其生成POCO类
假设我从上下文加载数据,但为了避免笛卡尔式生成,我不使用include,而是进行两个单独的查询
using(var context = new EntitiesContext())
{
var organizationsQuery = context.Where(FilterByParent);
var organizations = organizationsQuery.ToList();
var users = organizationsQuery.SelectMany(x => x.Users).Load();
}
假设连接的实体已加载是否安全?
如果我直接从DBSet加载用户,这会有什么不同吗?从数据库的角度来看: 假设连接的实体已加载是否安全 是的,这是安全的,因为首先由
EF Change Tracker
跟踪组织
,然后在下一个语句中调用Load
,EF知道应该将结果附加到被跟踪的实体
如果我直接从DBSet加载用户,这会有什么不同吗
事实上,使用Load
这种方式没有比Include
更好的了
如果您使用Include
EF将其转换为LEFT JOIN
,如果您使用Load
将其转换为内部JOIN
,如果您使用Contains
方法直接通过ID获取用户,则它将转换为Sql端的中的。
在Load
和Contains
情况下,您对Sql执行两次查询(两次),但在Include
情况下,它是一次完成的,因此总体上优于您的方法
您可以使用sqlprofiler
工具自己比较这些方法
更新:
根据对话,我意识到强尼的主要问题在于OrganizationUsers
对象的存在。因此,我建议将您的方法从DB First
更改为code First
,然后该对象可以显式存在!请在这条路上帮你
另外一种我想可能有效的方法是定制T4模板
,这似乎很难,但并非不可能 因此,entity framework将始终在include?@johnny5 EF中加载没有明确规范的中间表,将您的include
转换为一些联接,并将您的筛选器作为WHERE
子句应用于其中,并选择(在您的情况下)筛选的组织的所有用户。所有这些都将在Sql端完成,而不是在应用程序中完成。然后,结果用户及其OrganizationID将加载到您的应用程序中,并根据其OrganizationsId进行分组,并附加到您的Organizations对象。抱歉,我仍然有点困惑,我只想确保我们在同一页面上<代码>用户
没有组织ID
,组织
也没有用户ID
。它们仅通过中间表userinoorganizations
连接。因此,如果我加载用户
,然后在另一个查询中加载组织
,那么在哪一点加载用户组织
?第一个查询、第二个查询或两个查询?@johnny5返回问题中的示例代码,OrganizationUsers
和Users
只有在organizationsQuery时才会加载。选择many(x=>x.Users)。Load()代码>被执行我担心在测试后情况并非如此,EntityFramework将不会从一个选择多个加载关联表,我认为在这种情况下您忽略了中间表(OrganizationUsers)。选择仅选择对象,而不选择参照之间的连接。