实体框架。使用子实体保存大对象

时间:2018-06-11 21:59:07

标签: c# entity-framework

我从数据库中选择了大约这个结构的对象列表:

public static List<ProjectHeader> GetProjectHeadersWithEntries(int ProjectId)
    {
        using (var db = new ProjectContext(GlobalVariables.DBConnection))
        {
            var headers = db.ProjectHeaders.Where(x => x.ProjectId == ProjectId)
                .Include(x => x.ProjectRun)
                .Include(x => x.ProjectDeductionEntries)
                .Include("ProjectDeductionEntries.EmployeeDeduction")
                .Include("ProjectDeductionEntries.ProjectEntryType")
                .Include(x => x.ProjectEarningEntries)
                .Include("ProjectEarningEntries.ProjectEntryType")
                .Include("ProjectEarningEntries.Department")
                .Include(x => x.ProjectTaxEntries)
                .Include("ProjectTaxEntries.ProjectEntryType")
                .Include(x => x.Employee);
            return headers.ToList();
        }
    }

然后从这个列表中我获取某个对象并在那里进行计算,例如:

-ProjectHeader CurrentHeader = _ProjectHeaders.FirstOrDefault();

-CurrentHeader.ProjectTaxEntries - 分配了所有新对象,因为需要删除旧对象并且必须写入新对象。

-CurrentHeader.ProjectDeductionEntries - 更改现有对象。

-CurrentHeader.ProjectEarningEntries - 更改现有对象。

我怎么能写CurrentHeader完全进入数据库,只是我希望这些变化,即不会有覆盖CurrentHeader.ProjectRun,CurrentHeader.ProjectDeductionEntries.ProjectEntryType,CurrentHeader.ProjectTaxEntries.ProjectEntryType ...

这是我的录音功能和我的评论。我想这样做来创建一个全新的对象:

public static ProjectHeader SaveProjectHeaderWithEntries(ProjectHeader header)
{
using (var db = new ProjectContext(GlobalVariables.DBConnection))
{
db.Configuration.AutoDetectChangesEnabled = false;
db.Configuration.ValidateOnSaveEnabled = false;

var oldTaxes = db.ProjectTaxEntries.Where(x => x.ProjectHeaderId == header.ProjectHeaderId);

db.ProjectTaxEntries.RemoveRange(oldTaxes);

db.SaveChanges();

foreach (var item in header.ProjectTaxEntries)
            {
                //item.ProjectEntryType = null;
                //item.ProjectRun = null;
                //db.ProjectTaxEntries.AddOrUpdate(item);`

                if (item.ProjectEntryType != null)
                    db.Entry(item.ProjectEntryType).State = EntityState.Unchanged;
                if (item.ProjectRun != null)
                    db.Entry(item.ProjectRun).State = EntityState.Unchanged;

                if (item.ProjectTaxEntryId == 0)
                {
                    db.Entry(item).State = EntityState.Added;
                }
                else
                {
                    db.Entry(item).State = EntityState.Modified;
                }
            }
            //header.ProjectTaxEntries = null;
            //db.SaveChanges();

            //db.Entry(header.ProjectRun).State = EntityState.Unchanged;
            //db.Entry(header.Company).State = EntityState.Unchanged;
            //db.Entry(header.Employee).State = EntityState.Unchanged;

            foreach (var item in header.ProjectDeductionEntries)
            {
                //db.ProjectDeductionEntries.AddOrUpdate(item);
                //db.ProjectDeductionEntries.Attach(item);
                if (item.EmployeeDeduction != null)
                    db.Entry(item.EmployeeDeduction).State = EntityState.Unchanged;
                if (item.ProjectEntryType != null)
                    db.Entry(item.ProjectEntryType).State = EntityState.Unchanged;
                if (item.ProjectRun != null)
                    db.Entry(item.ProjectRun).State = EntityState.Unchanged;

                if (item.ProjectDeductionEntryId == 0)
                {
                    db.Entry(item).State = EntityState.Added;
                }
                else
                {
                    db.Entry(item).State = EntityState.Modified;
                }
            }
            foreach (var item in header.ProjectEarningEntries)
            { 
                //db.ProjectEarningEntries.AddOrUpdate(item);
                //db.ProjectEarningEntries.Attach(item);
                if (item.ProjectEntryType != null)
                    db.Entry(item.ProjectEntryType).State = EntityState.Unchanged;
                if (item.Employee != null)
                    db.Entry(item.Employee).State = EntityState.Unchanged;
                if (item.ProjectRun != null)
                    db.Entry(item.ProjectRun).State = EntityState.Unchanged;
                if (item.CompanyLocation != null)
                    db.Entry(item.CompanyLocation).State = EntityState.Unchanged;
                if (item.Department != null)
                    db.Entry(item.Department).State = EntityState.Unchanged;
                if (item.JobCode != null)
                    db.Entry(item.JobCode).State = EntityState.Unchanged;
                if (item.ProjectEarningEntryId == 0)
                {
                    db.Entry(item).State = EntityState.Added;
                }
                else
                {
                    db.Entry(item).State = EntityState.Modified;
                }
            }

            if (header.Company != null)
                db.Entry(header.Company).State = EntityState.Unchanged;
            if (header.Employee != null)
                db.Entry(header.Employee).State = EntityState.Unchanged;
            if (header.ProjectRun != null)
                db.Entry(header.ProjectRun).State = EntityState.Unchanged;
            if (header.ProjectHeaderId != 0)
            {
                db.Entry(header).State = EntityState.Modified;
            }
            else
            {
                db.Entry(header).State = EntityState.Added;
            }
            db.SaveChanges();
            db.Configuration.AutoDetectChangesEnabled = true;
            db.Configuration.ValidateOnSaveEnabled = true;

            return GetProjectHeaderWithEntries(header.ProjectHeaderId);
        }
    }

在这个版本中,我在行 db.Entry(item.EmployeeDeduction)上收到错误.State = EntityState.Unchanged;

附加&#39; Project.Business.Entities.ProjectEntryType&#39;类型的实体。失败,因为同一类型的另一个实体已具有相同的主键值。使用&#39;附加&#39;方法或将实体的状态设置为“未更改”#39;或者&#39;修改&#39;如果图中的任何实体具有冲突的键值。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,请使用&#39;添加&#39;方法或“添加”#39;实体状态跟踪图形,然后将非新实体的状态设置为“未更改”。或者&#39;修改&#39;酌情。

如果我在 EntityState.Detached 上更改 EntityState.Unchanged ,我会在 db.SaveChanges(); 错误中收到: 违反PRIMARY KEY约束&#39; PK_ProjectEntryType&#39;。无法在对象&#39; dbo.ProjectEntryType&#39;中插入重复键。重复键值为(200)。 声明已经终止。

EF希望在 ProjectEntryType 表中创建一个新条目,尽管我已将 EntityState.Detached 放在任何地方。 部分帮助在开始时做出记录:

foreach (var item in header.ProjectTaxEntries)
{
     item.ProjectEntryType = null;
     item.ProjectRun = null;
     db.ProjectTaxEntries.AddOrUpdate(item);
}
db.SaveChanges();

但是,在视图中的 _ProjectHeaders 对象列表中, ProjectEntryType ProjectRun 会丢失。在ProjectHeaders ProjectDeductionEntries.ProjectEntryType ProjectEarningEntries.ProjectEntryType ProjectTaxEntries.ProjectEntryType == null

如何使用EF仅记录我指定为Modified的对象?

0 个答案:

没有答案