具有linq的C#实体框架返回空引用

具有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

我对C#中的实体框架有问题。 我有两个实体,用户和用户角色。它们由关系用户*->1个用户角色绑定

每当我在函数中使用此查询时:

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);
}