2

編集

問題のスクリーンキャストを録画しました。ここで見つけることができます。時間があれば見てください。

AddOrUpdate 機能を実行する次のコードがありますが、代わりに既存のすべてのレコードが再作成されるため、結果としていくつかのニューヨークといくつかのアメリカがあります。クライアントから EntityState を転送しているため、クライアントでデータが変更された場合、クライアントはそれに応じて EntityState プロパティを更新し、それをサーバーに送信します。

    [HttpPost, HttpGet, HttpPut]
    public HttpResponseMessage SaveRecord(RecordViewModel record)
    {
        var model = Mapper.Map<Record>(record);

        if (!ModelState.IsValid)
        {
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
        }

        db.Attach(model);

        try
        {
            db.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
        }

        return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<RecordViewModel>(model));
    }

次の関数でエンティティをアタッチしています

    public void AttachAndMarkAs<T>(T entity, EntityState state, Func<T, object> id) where T : class
    {
        var entry = Entry(entity);

        if (entry.State == EntityState.Detached)
        {
            var set = Set<T>();

            T attachedEntity = set.Find(id(entity));

            if (attachedEntity != null)
            {
                var attachedEntry = Entry(attachedEntity);

                if (state != EntityState.Unchanged)
                {
                    attachedEntry.CurrentValues.SetValues(entity);
                    attachedEntry.State = state;
                }
            }
            else
            {
                entry.State = state;
            }
        }
    }

これは、次のものを介して中継されます。

    public void Attach(City entity)
    {
        if (entity != null)
        {
            Attach(entity.Country);

            AttachAndMarkAs(entity, entity.EntityState ?? EntityState.Added, instance => instance.Id);
        }
    }

    public void Attach(Country entity)
    {
        if (entity != null)
        {
            AttachAndMarkAs(entity, entity.EntityState ?? EntityState.Added, instance => instance.Id);
        }
    }

EntityState の値が正しいため、コードのどの部分がエンティティの更新ではなくエンティティの追加を処理するのかわかりません...

4

2 に答える 2

3

親エンティティの状態をプログラムで変更する場合、Entity Framework が子/参照エンティティを処理する方法に注意する必要があります。

さまざまなケースで物事がどのように機能するかをまとめたこの記事をご覧ください。

以下の例では、参照されるすべてのエンティティが自動的に次のように設定されると考えるかもしれませんModifiied

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Modified;
    // Do some more work... 
    context.SaveChanges();
}

しかし、実際にはそうはなりません。記事に書かれているように:

Modified とマークする必要があるエンティティが複数ある場合は、これらのエンティティごとに個別に状態を設定する必要があります。

最後に、あなたが であるAddOrUpdate場合に特定のケースを処理する必要がある方法は次のとおりです。PrimaryKeyInt

using (var context = new BloggingContext())
{
   context.Entry(blog).State = blog.BlogId == 0 ? EntityState.Added : EntityState.Modified;

   context.SaveChanges();
}
于 2013-06-25T08:06:29.083 に答える
3

IDに単純なものを使用している場合はint、次の方法を使用できます。

public abstract class BaseEntity
{
    public int Id { get; set; }
}

public void AddOrUpdate<T> (T entity) where T : BaseEntity
{
   if(entity.Id > 0){
      Entry(entity).State = EntityState.Modified;
   }
   else
   {
      Set<T>().Add(entity);
   }
}

// 

var model = Mapper.Map<Record>(record);
db.AddOrUpdate(model);
db.SaveChanges();
于 2013-06-24T20:41:52.673 に答える