0

MVC と POCO で EF5 を使用していますが、少し助けが必要です

切断された POCO を渡す更新機能があります。POCO には「ナビゲーション プロパティ」コレクションがあります。

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

Provider がロードされたとき (および古いコンテキストが閉じられたとき) には 2 つの Company オブジェクトがありましたが、現在は 4 つあり、更新したいと思います。

以下のコードは機能すると思いましたが、Companys は更新されません(ただし、Provider の非ナビゲーション プロパティ (string Name {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();

使用に成功した Provider with Companies の挿入については、次のとおりです。

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; 

EFが私を殺しているので、Julia Lermanの本を読みに行くつもりですが、その間に「会社」を更新するのを助けていただければ幸いです-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) の複合キーがないため、これは奇妙です。おそらく、ここで 2 回追加しようとしていますか?

Provider.Companies を事前に追加しないと、次のようになります。

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

4

1 に答える 1

-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);
        }
    }
}

それはあなたに続けるためにもう少し多くの情報を与えるはずです。

于 2013-02-26T19:15:25.597 に答える