DbContext没有保存

时间:2015-04-30 16:03:02

标签: c# entity-framework

自从我使用 DbContext 以来已经有一段时间了。我多年来一直在使用Serivce / Repository / UnitOfWork模式,这使我能够使用实体框架而不必担心如何添加/更新和删除。

现在我已经决定使用该设计模式的某些项目不适合(主要是在使用查找表时)。因此,我已经回归基础。

使用 DbContext 已找到获取信息,但现在我已经开始创建插入/更新数据的方法,我似乎发现了一个问题。 我相当肯定这个问题很简单,但我需要一些帮助:)

这是我的方法:

[HttpPost]
[Route("")]
public IHttpActionResult Import(IList<CollectionBindingModel> models)
{

    // If our ModelState is invalid, return a bad request
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    try
    {
        // Loop through our models
        foreach (var model in models)
        {

            // Create our collection
            var collection = new Collection()
            {
                CenterId = model.CenterId,
                Reference = model.Reference,
                CustomerReference = model.CustomerReference,
                CustomerName = model.CustomerName,
                CustomerBusinessName = model.CustomerBusinessName,
                SupplierName = model.SupplierName,
                CollectionCode = model.CollectionCode,
                Status = model.Status,
                CollectionDate = model.CollectionDate
            };

            // Add to our database context
            this.DbContext.Collections.Add(collection);
        }

        // Save our changes
        this.DbContext.SaveChanges();
    }
        catch (Exception ex)
    {

    }

    // Return Ok
    return Ok();
}

我刚刚添加了try / catch块用于测试目的。 当我从我的界面调用此方法时,它返回OK并且不会抛出任何错误,但是如果我检查数据库,我看到没有插入。

谁能告诉我为什么?

更新1

所以,深入挖掘一下。我有一个基本控制器,如下所示:

/// <summary>
/// Handles the creation of universal properties and methods
/// </summary>
public class BaseController : ApiController
{

    // Create our public properties
    protected DatabaseContext DbContext { get { return new DatabaseContext(); } }
    protected UserService UserService { get { return Request.GetOwinContext().GetUserManager<UserService>(); } }
    protected RoleService RoleService { get { return Request.GetOwinContext().GetUserManager<RoleService>(); } }
    protected ModelFactory ModelFactory { get { return new ModelFactory(this.Request, this.UserService); } }

    /// <summary>
    /// Used to return the correct error from an Identity Result
    /// </summary>
    /// <param name="result">The Identity Result to process</param>
    /// <returns></returns>
    protected IHttpActionResult GetErrorResult(IdentityResult result)
    {

        // If there is no result, return an internal server error
        if (result == null)
            return InternalServerError();

        // If we have an error
        if (!result.Succeeded)
        {

            // If we have some errors
            if (result.Errors != null)
            {

                // For each error, add to the ModelState
                foreach (var error in result.Errors)
                    ModelState.AddModelError("", error);
            }

            // If our ModelState is valid
            if (ModelState.IsValid)
            {

                // No ModelState errors are available to send, so just return an empty BadRequest.
                return BadRequest();
            }

            // Return a BadRequest with our ModelState
            return BadRequest(ModelState);
        }

        // Return null if no errors are found
        return null;
    }
}

从哪里撤出 DbContext 。 如果我将控制器方法更改为:

[HttpPost]
[Route("")]
public IHttpActionResult Import(IList<CollectionBindingModel> models)
{

    // If our ModelState is invalid, return a bad request
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    try
    {
        using (var context = new DatabaseContext())
        {

            // Loop through our models
            foreach (var model in models)
            {

                // Create our collection
                var collection = new Collection()
                {
                    CenterId = model.CenterId,
                    Reference = model.Reference,
                    CustomerReference = model.CustomerReference,
                    CustomerName = model.CustomerName,
                    CustomerBusinessName = model.CustomerBusinessName,
                    SupplierName = model.SupplierName,
                    CollectionCode = model.CollectionCode,
                    Status = model.Status,
                    CollectionDate = model.CollectionDate
                };

                // Add to our database context
                context.Collections.Add(collection);
            }

            // Save our changes
            context.SaveChanges();
        }
    }
    catch (Exception ex)
    {
        return InternalServerError(ex);
    }

    // Return Ok
    return Ok();
}

然后一切都保存好了。

2 个答案:

答案 0 :(得分:3)

每次访问DbContext属性时,您都在新建一个DbContect。

每次访问this.DbContext时,您都会获得DbContext类的新实例,因为您已经设置了属性...

protected DatabaseContext DbContext { get { return new DatabaseContext(); } }

所以这一行得到一个新的db上下文并添加集合对象...在这个循环的下一个itteration你会得到另一个DbContext的新实例并添加下一个...你不是要添加你的集合类到相同的对象实例...

// Add to our database context
this.DbContext.Collections.Add(collection);

这也是......

 // Save our changes
        this.DbContext.SaveChanges();

这意味着你基本上是在一个完全没有变化的全新DbContext实例上调用保存更改。您应该始终将实体添加并附加到DbContext的同一个实例,然后再调用保存更改。

您已在新代码中修复了该问题,因为您在基类的构造函数中创建了一个新的DbContext实例,然后在整个...中使用相同的实例...

// Create our public properties
    protected DatabaseContext DbContext { get; private set; }
    protected UserService UserService { get { return Request.GetOwinContext().GetUserManager<UserService>(); } }
    protected RoleService RoleService { get { return Request.GetOwinContext().GetUserManager<RoleService>(); } }
    protected ModelFactory ModelFactory { get { return new ModelFactory(this.Request, this.UserService); } }

    public BaseController()
    {
        this.DbContext = new DatabaseContext();
    }

这也可以,当你访问属性getter时,它会返回相同的实例,如果它已被初始化...或者首先初始化它然后返回它...

private DatabaseContext _dbContext;

protected DatabaseContext DbContext
{
    get { return this._dbContext ?? (this._dbContext = new DatabaseContext()); }
}

答案 1 :(得分:-1)

好的,我已经解决了这个问题,但我不明白为什么。

如果我将BaseController更改为:

/// <summary>
/// Handles the creation of universal properties and methods
/// </summary>
public class BaseController : ApiController
{

    // Create our public properties
    protected DatabaseContext DbContext { get; private set; }
    protected UserService UserService { get { return Request.GetOwinContext().GetUserManager<UserService>(); } }
    protected RoleService RoleService { get { return Request.GetOwinContext().GetUserManager<RoleService>(); } }
    protected ModelFactory ModelFactory { get { return new ModelFactory(this.Request, this.UserService); } }

    public BaseController()
    {
        this.DbContext = new DatabaseContext();
    }

    /// <summary>
    /// Used to return the correct error from an Identity Result
    /// </summary>
    /// <param name="result">The Identity Result to process</param>
    /// <returns></returns>
    protected IHttpActionResult GetErrorResult(IdentityResult result)
    {

        // If there is no result, return an internal server error
        if (result == null)
            return InternalServerError();

        // If we have an error
        if (!result.Succeeded)
        {

            // If we have some errors
            if (result.Errors != null)
            {

                // For each error, add to the ModelState
                foreach (var error in result.Errors)
                    ModelState.AddModelError("", error);
            }

            // If our ModelState is valid
            if (ModelState.IsValid)
            {

                // No ModelState errors are available to send, so just return an empty BadRequest.
                return BadRequest();
            }

            // Return a BadRequest with our ModelState
            return BadRequest(ModelState);
        }

        // Return null if no errors are found
        return null;
    }
}
然后一切正常。 请注意,我唯一改变的是将dbcontext的设置移动到构造函数。 我怀疑这是因为它以前的方式,每次有人请求它时都会创建一个新的数据库上下文。这次它在创建基本控制器时设置它。