使用UnityContainer时SaveChanges出错

时间:2016-05-09 19:38:06

标签: c# asp.net-mvc unity-container

我有一个使用Entity Framework 6的Asp.Net MVC 5.我正在使用 Unity.MVC5版本1.2.3.0

我遇到的问题是,在保存到数据库时,我会在某些情况下出现以下错误

  

附加信息:操作失败:关系可以   因为一个或多个外键属性是不可更改的   非空的。当对关系进行更改时,相关   foreign-key属性设置为空值。如果是外键的话   不支持null值,必须定义一个新的关系   必须为foreign-key属性分配另一个非null值,或者   必须删除不相关的对象。

在对问题进行故障排除后,我认为它与我如何配置Unity.MVC5有关。这是我的Unity.Config.cs

public static class UnityConfig
{
    public static void RegisterComponents()
    {
         var container = new UnityContainer();      
        // register all your components with the container here
        // it is NOT necessary to register your controllers    
        // e.g. container.RegisterType<ITestService, TestService>();
         container.RegisterTypes(AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default);

    container.RegisterType<IUnitOfWork, UnitOfWork>(new InjectionConstructor(new MasterContext()));

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

    }

}

所以我的控制器会有这样的东西

private IService _Service;
MyController(IService service)
{
    _Service = service;
}

然而,看起来数据没有刷新,虽然当我使用SQL事件探查器时,它显示正在进行调用,但数据没有刷新,因为我做了一个断点,它仍然有旧数据。如果我取消注入类的Unity.MVC,那么数据将被刷新并且savechanges可以正常工作。

我正在覆盖EF Context SaveChanges,这是代码

public override int SaveChanges()
{
    var autoDetectChanges = Configuration.AutoDetectChangesEnabled;

    try
    {
        Configuration.AutoDetectChangesEnabled = false;
        ChangeTracker.DetectChanges();

        var errors = GetValidationErrors().ToList();

        if (errors.Any())
        {
            throw new DbEntityValidationException("Validation errors found during save.", errors);
        }

        //For modified column
        var changedInfo = ChangeTracker.Entries().Where(t => t.State == EntityState.Modified)
            .Select(t => new
            {
                    Original = t.OriginalValues.PropertyNames.ToDictionary(pn => pn, pn => t.OriginalValues[pn]),
                    Current = t.CurrentValues.PropertyNames.ToDictionary(pn => pn, pn => t.CurrentValues[pn]),
                    objectContext = ((IObjectContextAdapter)this).ObjectContext,
                    ent = t,
            });
        foreach (var item in changedInfo)
        {
            if (GetTableInformation.GetTableName(item.objectContext, item.ent) != "HistoryLogs")
            {
                var result = GetDifference.GetChangedValues(item.Original, item.Current, item.objectContext, item.ent);
                HistoryLog history = new HistoryLog();
                history.Description = result[0];
                history.TableFields = result[1];
                history.UserId = userId;
                history.TableAction = "Modified";
                history.PrimaryKeyValue = Convert.ToInt32(result[2]);
                history.TableName = result[3];
                if (history.TableName == "MainRates")
                {
                    MainRate rate = MainRates.SingleOrDefault(r => r.RateId == history.PrimaryKeyValue);
                    history.InstitutionId = rate.InstitutionId;
                }
                else if (history.TableName == "ProgramRates")
                {
                    ProgramRate rate = ProgramRates.SingleOrDefault(r => r.RateId == history.PrimaryKeyValue);
                    history.InstitutionId = rate.InstitutionId;
                }
                else
                {
                    int institutiondId;
                    if (int.TryParse(result[4], out institutiondId))
                    {
                        history.InstitutionId = institutiondId;
                    }
                    else
                    {
                        history.InstitutionId = null;
                    }
                }
                //InstitutionName and OPEID are being updated by trigger(executer after each insert operations)

                //Check if there is any modified column or not
                if (!string.IsNullOrEmpty(history.TableFields))
                    HistoryLogs.Add(history);
            }
        }

        //For Deleted columns
        var deletedInfo = ChangeTracker.Entries().Where(t => t.State == EntityState.Deleted)
            .Select(t => new
            {
                Original = t.OriginalValues.PropertyNames.ToDictionary(pn => pn, pn => t.OriginalValues[pn]),
                objectContext = ((IObjectContextAdapter)this).ObjectContext,
                ent = t,
            });
        foreach (var item in deletedInfo)
        {
            if (GetTableInformation.GetTableName(item.objectContext, item.ent) != "HistoryLogs")
            {
                var result = GetDifference.GetDeletedValues(item.Original, item.objectContext, item.ent);
                HistoryLog history = new HistoryLog();
                history.Description = result[0];
                history.TableFields = result[1];
                history.UserId = userId;
                history.TableAction = "Deleted";
                history.PrimaryKeyValue = Convert.ToInt32(result[2]);
                history.TableName = result[3];
                if (history.TableName == "MainRates")
                {
                    int locationRateId = (int)item.Original["LocationRateId"];
                    history.InstitutionId = LocationRates.SingleOrDefault(l => l.Id == locationRateId).InstitutionId;
                }
                else if (history.TableName == "ProgramRates")
                {
                    ProgramRate rate = ProgramRates.SingleOrDefault(r => r.RateId == history.PrimaryKeyValue);
                    history.InstitutionId = rate.InstitutionId;
                }
                else
                {
                    history.InstitutionId = result[4] == null ? null : (int?)int.Parse(result[4]);
                }
                //InstitutionName and OPEID are being updated by trigger(executer after each insert operations)
                history.InstitutionName = "";
                history.OpeidNumber = "";

                //Check if there is any modified column or not
                if (!string.IsNullOrEmpty(history.TableFields))
                    HistoryLogs.Add(history);
            }
        }
        // For data that is added
        string[] applicableTables = new string[] { "EligiblePrograms", "Fees", "LocationRates", "MainRates", "ProgramRates" };
        var addedInfo = ChangeTracker.Entries().Where(t => t.State == EntityState.Added)
            .Select(t => new
            {
                Current = t.CurrentValues.PropertyNames.ToDictionary(pn => pn, pn => t.CurrentValues[pn]),
                ObjectContext = ((IObjectContextAdapter)this).ObjectContext,
                Entity = t,
            }).ToList();

        //Placing this here adds the primary keys to the new values before saving their history.
        Configuration.ValidateOnSaveEnabled = false;
        int rVal = base.SaveChanges();

        foreach (var item in addedInfo)
        {
            string tableName = GetTableInformation.GetTableName(item.ObjectContext, item.Entity);
            if (applicableTables.Contains(tableName))
            {
                var result = GetDifference.GetDeletedValues(item.Current, item.ObjectContext, item.Entity);
                HistoryLog history = new HistoryLog();
                history.Description = result[0];
                history.TableFields = result[1];
                history.UserId = userId;
                history.TableAction = "Added";
                history.PrimaryKeyValue = Convert.ToInt32(result[2]);
                history.TableName = result[3];
                if (history.TableName == "MainRates")
                {
                    history.InstitutionId = ((MainRate)item.Entity.Entity).InstitutionId;
                }
                else if (history.TableName == "ProgramRates")
                {
                    history.InstitutionId = ((ProgramRate)item.Entity.Entity).InstitutionId;
                }
                else
                {
                    history.InstitutionId = result[4] == null ? null : (int?)int.Parse(result[4]);
                }
                history.InstitutionName = "";
                history.OpeidNumber = "";

                //Check if there is any modified column or not
                if (!string.IsNullOrEmpty(history.TableFields))
                    HistoryLogs.Add(history);
            }
        }
        rVal += base.SaveChanges();
        return rVal;
    }
    finally
    {
        Configuration.AutoDetectChangesEnabled = autoDetectChanges;
    }
}

然后我的Service类将执行以下操作:

        Header header = _uow.MyRepository.GetByHeaderId(model.Id, model.HeaderId);

        header.WebAddresses = string.Join(",", model.WebAddresses.ToArray());
        header.Date = DateTime.Parse(model.Date);
        header.IsField1 = model.Field1;
        header.Field2 = model.Field2;
        header.Field3 = model.Field3;

        _uow.SaveChanges();

0 个答案:

没有答案