EF POCO无法更新导航属性

时间:2013-02-26 18:54:53

标签: entity-framework

我正在使用EF5和MVC以及POCO,需要一些帮助

我有一个更新函数,它传递了一个断开连接的POCO。 POCO有一个“导航属性”集合,例如:提供商有

public virtual ICollection<Company> Companies { get; set; }

当加载Provider时(旧的上下文关闭)它有两个Company对象,现在它有四个,我想更新。

我认为下面的代码可能有效,但公司未更新(但提供商的非导航属性(如字符串名称{get; set}仍然更新确定)并且没有错误

public void Update(Provider entity)
{                        
            // Existing entity
            _context.Entry(entity).State = EntityState.Modified;

            if (entity.Companies.Any())
            {
                //try to tell EF about the companies
                foreach (var company in entity.Companies)
                {
                    //the company exists already - let the context know....                        
                    _context.Entry(company).State = EntityState.Modified;
                    _context.Companies.Attach(company);
                }
            }                    
}

......以及之后:_unitOfWork.SaveChanges();

对于我已成功使用的公司的提供者插入:

if (entity.Companies.Any())
{
    //these are not to be created - they exist - 
    //I want EF to add them as nav properties
    foreach (var company in entity.Companies)
    {
        //the company exists already - let the context know....
        _pvpContext.Companies.Attach(company);
    }
}

// New entity
_pvpContext.Entry(entity).State = EntityState.Added; 

我打算去阅读Julia Lerman的书,因为EF杀了我 - 但我真的很感激在此期间更新'公司'的任何帮助 - Thx

编辑: 我尝试了@Manos的善意建议:

List<Company> companies = new List<Company>();
if (entity.Companies != null && entity.Companies.Any())
{
    //pull out the Companies from the POCO
    companies = entity.Companies.ToList();

    //remove them
    entity.Companies = new Collection<Company>();
    entity.Companies.Clear();
}

// pass existing entity to the context, tagged as modified
_pvpContext.Entry(entity).State = EntityState.Modified;

if (companies.Any())
{
    //now re-add the companies while the context is listening. ffs.
    foreach (var company in companies)
    {
        entity.Companies.Add(company);
    }
}

如果我将Provider.Companies添加到上下文中(比如在插入中),我得到:

  

违反PRIMARY KEY约束'PK__tmp_ms_x__679519B7F943FD8D'。   无法在对象'dbo.ProviderCompany'中插入重复键。该   重复键值为(5,3)

  • 这是奇怪的,因为没有(提供者5,公司3)的复合键 - 所以也许它试图在这里添加两次?

如果我没有预先添加Provider.Companies,我会得到:

  

at System.Data.Entity.Internal.InternalContext.SaveChanges()at   System.Data.Entity.Internal.LazyInternalContext.SaveChanges()at   System.Data.Entity.DbContext.SaveChanges()

1 个答案:

答案 0 :(得分:-1)

我只有4.1进行测试,但尝试将其作为基本逻辑:

public void Update(Provider entity)
{                        
    // Existing entity
    Provider contextProvider = _context.Entry(entity);
    contextProvider.Companies.Clear();        

    foreach (var company in entity.Companies)
    {
        contextProvider.Companies.Add(company);
    }

}

这需要稍微改进,以便只添加新公司,而不是完全删除和恢复,但它应该有效。

编辑以回复评论:

尝试使用以下内容捕获SaveChanges()抛出的异常:

try {
    _unitOfWork.SaveChanges();
} catch (System.Data.Entity.Validation.DbEntityValidationException e) {
    foreach (var k in e.EntityValidationErrors) {
        foreach (var e1 in k.ValidationErrors) {
            Console.WriteLine("{0} - {1}", e1.PropertyName, e1.ErrorMessage);
        }
    }
}

它应该为您提供更多信息。