10

現在、既存のデータと新しいデータを含むモデルがあります。

例として、これは私のモデルです

 public class NameDetails
    {
        public int Id { get; set; }
        public string Name { get; set; }

    }

これは現在持っているモック データです。

  List<NameDetails> Names = new List<NameDetails>{

                new  NameDetails{Id = 1, Name = "Name 1"},
                new NameDetails{Id = 2 , Name = "Name 2"},
            };

ここで、これをデータベースに保存する必要があるとします..テーブルには既に id = 1 があるので、id = 2 を追加する必要がある場合は更新する必要があります...どうすればそれを行うことができますか?

以前、リポジトリを使用して保存を作成したときに、追加または編集 Add のいずれかを実行しました。

 context.NameDetails.Add(NameDetails); 
    context.SaveChanges(); 

またはそのように編集し、

var recordToUpdate = context.NameDetails.FirstOrDefault(x => x.Id== 1);
recordToUpdate.Name = "New name";
context.SaveChanges();

つまり、リストをループして、何が新しくて何がそうでないかを調べなければならないということですか..または別の方法がありますか?

4

4 に答える 4

2

Entity Framework で正常に機能するいくつかの規則を使用できます。

たとえばIDENTITY(1,1)、データベースで使用する場合 (挿入された行の ID を自動的に生成するため)、エンティティ プロパティはStoreGeneratedPatternset asを使用する必要Identityがあり (モデル ファースト アプローチの場合)、値をId持つプロパティは、まだ追加されていないことを意味しますデータベース0

次に、何を追加し、何を更新するかを簡単に決定できます。以下は疑似 (テストされていない) コードです。

foreach (var entity in entities)
{
    if (entity.Id == 0)
    {
        // Adds to the context for a DB insert
        context.Entities.Add(entity);
    }
    else
    {
        // Updates existing entity (property by property in this example, you could update
        // all properties in a single shot if you want)
        var dbEntity = context.Entities.Single(z => z.Id == entity.Id);
        dbEntity.Prop1 = entity.Prop1;
        // etc...
    }
}

context.SaveChanges();
于 2013-07-24T12:50:47.387 に答える
1

EF5+ のみ:

アイテムが新しいかどうかを検出する方法がある場合 (ken2k の回答のように Id == 0 が適切です)、これを実行して、物事をマップする必要がないようにすることができます。

foreach(var entity in entities)
{
    context.NameDetails.Attach(entity);
    context.Entry(entity).State = IsNewEntity(entity) 
                                  ? EntityState.Added
                                  : EntityState.Modified;
}

これにより、新しいエンティティの INSERT と古いエンティティの UPDATE を作成するように EntityFramework に指示されます。

于 2013-07-24T22:00:27.693 に答える
0

これを試して:

var nameIds = Names.Select(n => n.Id);

var recordsToUpdate = context.NameDetails.Where(x => nameIds.Contains(x.Id));
于 2013-07-24T12:34:52.717 に答える
0

Entity Framework は、このような状況ではうまく機能しません。これにより、探しているものに近づくはずです。

public class NameDetails
{
    public int Id {get;set;}
    public string Name {get;set;}
}

List<NameDetails> Names = new List<NameDetails>
    {
        new  NameDetails{Id = 1, Name = "Name 1"},
        new NameDetails{Id = 2 , Name = "Name 2"},
    };


var toFetch = Names.Select(n => n.Id).ToArray();
var association = context.NameDetails
                         .Where(n => toFetch.Contains(n.Id))
                         .ToDictionary(n => n.Id);

foreach(var name in Names)
{
    NameDetails existing;
    if(association.TryGetValue(name.Id, out existing))
    {
        // It exists, map the properties in name to existing
    }
    else
    {
        // It's new, perform some logic and add it to the context
        context.NameDetails.Add(name);
    }
}

context.SaveChanges()

AddOrUpdateまたは、アップサートを実行するEntity Framework Migration を乗っ取ることもできます。

// You need a namespace import of  System.Data.Entity.Migrations
context.NameDetails.AddOrUpdate(names.ToArray());
context.SaveChanges();

私はこれを試していませんが、AddOrUpdate私を逃れる追加のロジックがない限り、うまくいくはずです。

于 2013-07-24T12:42:47.020 に答える