具有linq的C#实体框架返回空引用
我对C#中的实体框架有问题。 我有两个实体,用户和用户角色。它们由关系用户*->1个用户角色绑定 每当我在函数中使用此查询时:具有linq的C#实体框架返回空引用,c#,linq,frameworks,entity,C#,Linq,Frameworks,Entity,我对C#中的实体框架有问题。 我有两个实体,用户和用户角色。它们由关系用户*->1个用户角色绑定 每当我在函数中使用此查询时: User user = context.User.Where(i => i.id == id).FirstOrDefault(); return user.UserRole.accessLevel; 查询返回user,但UserRole为null。用户表具有与UserRole的id相关的roleId,以及调试正确时的roleId值,尽管UserRole实体为nu
User user = context.User.Where(i => i.id == id).FirstOrDefault();
return user.UserRole.accessLevel;
查询返回user,但UserRole为null。用户表具有与UserRole的id相关的roleId,以及调试正确时的roleId值,尽管UserRole实体为null。这很奇怪,因为以前从未发生过
我已经确定了我在模型和数据库中的关系是正确的。我已将正确的行添加到数据库中
编辑:
抱歉,我应该提到我使用自定义可测试数据库控制器:
public class DBController : IUnitOfWork
{
readonly ObjectContext context;
const string ConnectionStringName = "MarketPlaceDBEntities";
public DBController()
{
var connectionString =
ConfigurationManager
.ConnectionStrings[ConnectionStringName]
.ConnectionString;
context = new ObjectContext(connectionString);
}
public void Commit()
{
context.SaveChanges();
}
public IObjectSet<Category> Category
{
get { return context.CreateObjectSet<Category>(); }
}
public IObjectSet<ItemComment> ItemComment
{
get { return context.CreateObjectSet<ItemComment>(); }
}
public IObjectSet<ItemRating> ItemRating
{
get { return context.CreateObjectSet<ItemRating>(); }
}
public IObjectSet<Item> Item
{
get { return context.CreateObjectSet<Item>(); }
}
public IObjectSet<ItemSale> ItemSale
{
get { return context.CreateObjectSet<ItemSale>(); }
}
public IObjectSet<ItemScreenshot> ItemScreenshot
{
get { return context.CreateObjectSet<ItemScreenshot>(); }
}
public IObjectSet<UserRole> UserRole
{
get { return context.CreateObjectSet<UserRole>(); }
}
public IObjectSet<User> User
{
get { return context.CreateObjectSet<User>(); }
}
}
尝试急切地加载
UserRole
(加入):
或先启用延迟加载:
context.ContextOptions.LazyLoadingEnabled = true;
context.User.Where(i => i.id == id).FirstOrDefault();
否则与数据库中的
用户角色没有关系…最简单的方法是:
UserRole user = context.User.Where(i => i.id == id).Select(i => i.UserRole);
return user.accessLevel;
编辑:
假设您在用户
和用户角色
User user = context.User.Where(i => i.id == id).FirstOrDefault();
UserRole role = context.UserRole.Where(i => user.Contains(i.id)).FirstOrDefault();
return role.accessLevel;
int roleid = Convert.ToInt32(context.User.Where(i => i.id == id).Select(i => i.roleid));
UserRole role = context.UserRole.Where(i => i.id == roleid).FirstOrDefault();
return role.accessLevel;
假设User
和UserRole
User user = context.User.Where(i => i.id == id).FirstOrDefault();
UserRole role = context.UserRole.Where(i => user.Contains(i.id)).FirstOrDefault();
return role.accessLevel;
int roleid = Convert.ToInt32(context.User.Where(i => i.id == id).Select(i => i.roleid));
UserRole role = context.UserRole.Where(i => i.id == roleid).FirstOrDefault();
return role.accessLevel;
另外,如果您有关系,但看不到User
下的UserRole
,请尝试将其添加到您的模型中
public IDisposable User()
{
YourDataContext context = new YourDataContext();
Type ct = context.User.GetType();
return (IDisposable)(ct);
}
试试这个
User-User=context.User.Where(i=>i.id==id.FirstOrDefault();
返回user==null?null:user.UserRole.accessLevel代码>假设您的问题是,为什么这不起作用?该roleId
没有UserRole
,或者您需要再次检查模型中的关系。您是否已指定用户类上的UserRole属性为virtual?类似地,在用户类上,您应该将用户集合(假设您有一个)标记为虚拟。另外,您可以将查询重写为User User=context.User.Find(id).context.User不知何故没有Find方法…您好,看起来很有希望。我也看到有人向我推荐了这个,但在我的案例中找不到如何做到这一点。但是,没有[…]Include方法。LazyLoading在模型实例化中启用。我应该提到,我使用可测试的数据库控制器,它实现了IUnitOfWork接口。我将编辑包含详细信息的帖子。Include
可在类ObjectQuery
(ObjectSet:ObjectQuery)中找到。创建性能更好的SQL查询(连接而不是两个查询)需要此方法。最后,您应该创建自己的接口:IMyObjectSet:IObjectSet{void Include();}
,其中包括此方法。@ricoster我完全同意此答案,使用时+1。Include
和LazyLoadingEnabled
因为我使用的是自定义数据库控制器,所以我不能像您的示例中那样使用Include,但是在我的控制器实例化中启用LyZyLoad确实解决了这个问题,谢谢你应该考虑使用<代码>包含,因为它比懒惰加载快得多。设想一个具有导航属性的实体列表;如果延迟加载每个导航属性,则列表将有一个查询,每个项将有另一个查询。如果使用“急切加载”,则只有一个查询会花费更多的时间,因为它包含SQL联接。这会忽略我的用户角色(为null),我不希望发生这种情况,因为我使用的是用户角色的值。请阅读我的编辑。您的解决方案似乎可行,但这忽略了实体框架的用途,或者至少是我创建DBController类的原因。最奇怪的是,它以前是按我的方式工作的,我不记得在它出错之前我做了什么。我也编辑了我的帖子,但到目前为止,我在你的模型中看不到User
和UserRole
之间的任何关联(关系),所以试试这些,或者干脆重新考虑使用@ricoster解决方案。
public IDisposable User()
{
YourDataContext context = new YourDataContext();
Type ct = context.User.GetType();
return (IDisposable)(ct);
}