且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

SaveChangesAsync()方法不更新数据库

更新时间:2023-02-08 16:34:12

我终于发现自己在做错什么. 实际上,我正在使用"Unity"(版本5.8.6).我上次与.NET Framework同时更新了Unity软件包.

我这样制作了UnityConfig.cs:

public static void ConfigureUnityContainer(IUnityContainer container)
{
    // some other resgistration
    container.RegisterType<MyEntities>(new PerResolveLifetimeManager());
}

错误与管理器的类型有关.正确的是 PerRequestLifetimeManager :

public static void ConfigureUnityContainer(IUnityContainer container)
{
    // some other resgistration
    container.RegisterType<MyEntities>(new PerRequestLifetimeManager());
}

我对 PerRequestLifetimeManager 的理解是,容器将解析http请求中对象的同一实例,而 PerResolveLifetimeManager 将标记类型,以便实例可在整个构建对象图中重用.

总而言之,对于 PerRequestLifetimeManager ,在不同的http请求中,我们将具有不同的已解析对象.

I have a web application with:

  • Entity Framework 6.1.3
  • Framework .NET 4.5.1

I made an upgrade of .NET Framework from version 4.5.1 to 4.6.2.

Since that, the "SaveChangesAsync()" of "System.Data.Entity" method does not updating my database anymore.

I can not find if it's because of the .NET framework package or some compatibility issues between Entity Framework 6.1.3 and .NET Framwork 4.6.2 for "SaveChangesAsync()" method... I'm a lost!

Here's some samples:

Service class

public async Task<MyActionResponseModel> UpdateSomething(Catalogue catalogue)
{
    if (catalogue== null) throw new ArgumentNullException("catalogue is null");
    var response = new ActionAddResponse();

    var catalogueToUpdate = await _catalogueRepository.GetCatalogueById(catalogue.Id);
    var myDate = new DateTime();
    if (catalogue.EndDate != null)
    {
        myDate = catalogue.EndDate.Value;
        myDate = myDate.Date.AddHours(23).AddMinutes(59);
    }

    catalogueToUpdate.Year = catalogue.Year;
    catalogueToUpdate.StartDate = catalogue.StartDate;
    catalogueToUpdate.EndDate = catalogue.EndDate!= null ? myDate : catalogue.EndDate;
    catalogueToUpdate.Tax = catalogue.Tax;
    catalogueToUpdate.Online = Convert.ToBoolean(catalogue.Online);
    catalogueToUpdate.RefNote = catalogue.RefNote;

    await _unitOfWork.SaveAsync();

    response.Success = true;
    response.Message = string.Format("Catalogue has been update");

    return response;
}

UnitOfWork class

public class UnitOfWork:IUnitOfWork
{    
    public async Task SaveAsync()
    {
        await _context.SaveChangesAsync(); // System.Data.Entity
    }
}

package.config

<packages>
  <package id="EntityFramework" version="6.1.3" targetFramework="net462" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.6" targetFramework="net451" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.6" targetFramework="net451" />
  <package id="Newtonsoft.Json" version="10.0.1" targetFramework="net451" />
</packages>

I already checked my async/await choregraphy and everything seems correct. So what is happening right there?

Thank you in advance.

I finally found what I was doing wrong. In fact I'm using "Unity" (verison 5.8.6). I made an update of my Unity package at the same time as the .NET Framework last time.

I made my UnityConfig.cs like this:

public static void ConfigureUnityContainer(IUnityContainer container)
{
    // some other resgistration
    container.RegisterType<MyEntities>(new PerResolveLifetimeManager());
}

The error is on the type of the manager. The correct one is PerRequestLifetimeManager:

public static void ConfigureUnityContainer(IUnityContainer container)
{
    // some other resgistration
    container.RegisterType<MyEntities>(new PerRequestLifetimeManager());
}

What I understood for PerRequestLifetimeManager is that the container will resolve the same one instance of the object in http request while PerResolveLifetimeManager will mark the type so that instances are reused across the build-up object graph.

In summary, with PerRequestLifetimeManager, in different http requests we will have different resolved objects.