C# 实体上未加载关联属性
我有三个相关实体,最好用这个图来描述: 当我加载用户时,使用以下代码加载C# 实体上未加载关联属性,c#,.net,entity-framework,C#,.net,Entity Framework,我有三个相关实体,最好用这个图来描述: 当我加载用户时,使用以下代码加载用户对象,即不为null,但是用户对象上的角色和部门属性为null,尽管用户数据库记录具有这些关联的有效FK值 using (var productionEntities = new ProductionEntities()) { var userName = GetUserName(); User u = (from usr in productionEntities.UserSet
用户
对象,即不为null,但是用户
对象上的角色
和部门
属性为null,尽管用户数据库记录具有这些关联的有效FK值
using (var productionEntities = new ProductionEntities())
{
var userName = GetUserName();
User u = (from usr in productionEntities.UserSet
where usr.UserName == userName
select usr).FirstOrDefault();
if (u == null)
{
throw new KpiSecurityException("No local database entry found for user.") { UserName = userName };
}
return u.Department.DeptName;
}
旁白:我完成了整个任务,只是因为ASP.NET MembershipProvider不支持像department这样的用户“元数据”,而且我还必须使用ProfileProvider,代价是巨大的数据库膨胀。您必须显式加载此属性
User u = (from usr in productionEntities.UserSet
where usr.UserName == userName
select usr).FirstOrDefault();
if (u == null)
{
throw new KpiSecurityException("No local database entry found for user.") { UserName = userName };
}
if (!u.RoleReference.IsLoaded)
{ u.RoleReference.Load(); }
if (!u.DeparmentReference.IsLoaded)
{ u.DeparmentReference.Load(); }
或者在查询中包含此实体
User u = (from usr in productionEntities.UserSet.Include("Role").Include("Department")
where usr.UserName == userName
select usr).FirstOrDefault();
必须显式加载此属性
User u = (from usr in productionEntities.UserSet
where usr.UserName == userName
select usr).FirstOrDefault();
if (u == null)
{
throw new KpiSecurityException("No local database entry found for user.") { UserName = userName };
}
if (!u.RoleReference.IsLoaded)
{ u.RoleReference.Load(); }
if (!u.DeparmentReference.IsLoaded)
{ u.DeparmentReference.Load(); }
或者在查询中包含此实体
User u = (from usr in productionEntities.UserSet.Include("Role").Include("Department")
where usr.UserName == userName
select usr).FirstOrDefault();
既然你只需要部门名称,那就这样吧;这样,您只能查询数据库一次:
using (var productionEntities = new ProductionEntities())
{
var userName = GetUserName();
var u = (from usr in productionEntities.UserSet
where usr.UserName == userName
select new
{
DeptName = usr.Department.DeptName
}).FirstOrDefault();
if (u == null)
{
throw new KpiSecurityException("No local database entry found for user.") { UserName = userName };
}
return u.DeptName;
}
既然你只需要部门名称,那就这样吧;这样,您只能查询数据库一次:
using (var productionEntities = new ProductionEntities())
{
var userName = GetUserName();
var u = (from usr in productionEntities.UserSet
where usr.UserName == userName
select new
{
DeptName = usr.Department.DeptName
}).FirstOrDefault();
if (u == null)
{
throw new KpiSecurityException("No local database entry found for user.") { UserName = userName };
}
return u.DeptName;
}
这将导致三个DB查询;只需要一个。+1用于教我IsLoaded和Load()成员。我知道有类似的东西,但我只是不知道在哪里可以找到它。Ishtar,
Load()
生成了太多的查询,Include
生成了过于复杂的查询。无论是哪种方式,都会使数据库服务器的工作变得比返回单个字段更困难。克雷格:但问题是加载引用的属性,而不是选择单个字段。在LINQ中,实体并不是实现这一点的另一种正确方法。使用存储过程列出和选择将适得其反。他的方法返回一个字段。为什么还要选择其他东西呢。没有人建议存储进程;那将是浪费精力。L2E已经处理好了。我不知道为什么要执行一个查询(或多个查询!),当您只需要从方法返回一个值时,它会从多个对象返回几十个属性;只需要一个。+1用于教我IsLoaded和Load()成员。我知道有类似的东西,但我只是不知道在哪里可以找到它。Ishtar,Load()
生成了太多的查询,Include
生成了过于复杂的查询。无论是哪种方式,都会使数据库服务器的工作变得比返回单个字段更困难。克雷格:但问题是加载引用的属性,而不是选择单个字段。在LINQ中,实体并不是实现这一点的另一种正确方法。使用存储过程列出和选择将适得其反。他的方法返回一个字段。为什么还要选择其他东西呢。没有人建议存储进程;那将是浪费精力。L2E已经处理好了。我不知道为什么要执行一个查询(或多个查询!),当您只需要从该方法返回一个值时,它会从多个对象返回几十个属性。