【问题标题】:Entity Framework Code First NullReferenceException when adding to a dbset of class that contains a list添加到包含列表的类的 dbset 时,Entity Framework Code First NullReferenceException
【发布时间】:2016-06-17 10:52:17
【问题描述】:

首先,我对 Entity Framework 的东西和 WebAPI 比较陌生,但是,我目前正在编写一个有趣的 Web API,其中涉及一个人能够创建一个能够创建“企业”的主“企业”帐户和创建并附加子帐户。有单独的表格来跟踪在企业帐户下创建的企业以及附属于这些企业的工人列表。

给定以下类/代码:

商务舱:

public class Business
{
    public int Id { get; set; }

    public string BusinessAccount { get; set; }
    public string BusinessName { get; set; }                

    public List<Worker> Workers { get; set; }
}

SchedulerDbContext:

public class SchedulerDbContext : DbContext
{
    public SchedulerDbContext()
        : base("SchedulerDbContext")
    {

    }

    public virtual DbSet<Business> Businesses { get; set; }
    public virtual DbSet<Worker> Workers { get; set; }

}

BusinessController:(仅显示相关部分)

[Route("Create")]        
public IHttpActionResult Create(string name)
{
    if (String.IsNullOrWhiteSpace(name))
    {
        ModelState.AddModelError("BusinessNameError", "Invalid Business Name Entered.");
        return BadRequest(ModelState);
    }

    Business business = new Business()
    {
        BusinessName = name,
        BusinessAccount = User.Identity.Name,
        Workers = new List<Worker>() //<----a
    };

    using (var db = new SchedulerDbContext())
    {
        db.Businesses.Add(business); //<----b
        db.SaveChanges();
    }

    return Ok(business);
}

UserController:(仅相关部分)

[Route("Register")]
public async Task<IHttpActionResult> Register(UserModel userModel)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    AccountUser user = new AccountUser
    {
        UserName = userModel.UserName,
        Email = userModel.Email,
        BusinessAccount = User.Identity.Name
    };

    IdentityResult result = await this.SchedUserManager.RegisterUser(user, userModel);
    IHttpActionResult errorResult = GetErrorResult(result);
    if (errorResult != null)
    {
        return errorResult;
    }

    result = await this.SchedUserManager.AddToRoleAsync(user.Id, defaultRole);
    errorResult = GetErrorResult(result);
    if (errorResult != null)
    {
        return errorResult;
    }


    using (var db = new SchedulerDbContext())
    {
        var query = from record in db.Businesses
                    where record.Id == userModel.BusinessId
                    select record;
        var business = query.First();

        var worker = new Worker()
        {
            FirstName = userModel.FirstName,
            LastName = userModel.LastName,
            Email = userModel.Email
        };

        if (business.Workers == null) { business.Workers = new List<Worker>(); } //<----c

        business.Workers.Add(worker); //<----d
        db.SaveChanges();
    }

    return Ok();
}

现在代码已经结束了。我用箭头标记了多个点。现在我的问题是......

在 BusinessController 的 Create() 函数中创建业务时,我为 Workers 属性分配了一个新列表,如 //

现在,在 UserController 的 Register() 函数中创建用户帐户以附加到该业务时,我遇到了一个问题。如果在箭头 //

我很好奇的是为什么 //

【问题讨论】:

    标签: c# entity-framework asp.net-web-api ef-code-first


    【解决方案1】:

    因为 EF 默认不加载所有外部行。您要么需要明确告诉它加载工作人员,要么为该属性启用延迟加载。

    显式加载:

    var query = from record in db.Businesses
                    where record.Id == userModel.BusinessId
                    select record;
    var business = query.Include("Workers").First();
    //                   ^^^^^^^^^^^^^^^^^^
    

    允许延迟加载启动该关系:

    public virtual List<Worker> Workers { get; set; }
    //     ^^^^^^^
    

    【讨论】:

    • 谢谢。我认为有一些我遗漏的东西可以解决我的问题。照你说的做了,效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    • 2013-01-01
    相关资源
    最近更新 更多