web-dev-qa-db-ja.com

Entity Frameworkで挿入されたエンティティのIDを取得する方法

Asp.netのEntity Frameworkに問題があります。データベースにオブジェクトを追加するたびにId値を取得したいです。これどうやってするの?

521
ahmet

とても簡単です。 DBで生成されたID(MS SQLのIDENTITYなど)を使用している場合は、関連するObjectSetのエンティティをSaveChangesおよびObjectContextに追加するだけで済みます。 Idは自動的に埋められます。

using (var context = new MyContext())
{
  context.MyEntities.AddObject(myNewObject);
  context.SaveChanges();

  int id = myNewObject.Id; // Yes it's here
}

自動生成されたINSERTが使用されている場合、デフォルトでエンティティフレームワークはIdの後にSELECT SCOPE_IDENTITY()を付けます。

873
Ladislav Mrnka

Ladislav Mrnkaの答え Entity Frameworkの使用時にIDを正常に取得するために使用していましたが、使用しなかったため(必要でない場所で使用したため)ここに掲載しています。ここでの調査結果インケースでは、人々は私が抱えていた問題を「解決」しようとしています。

Customerと外部キーの関係があるOrderオブジェクトを考えます。新しい顧客と新しい注文を同時に追加したとき、私はこのようなことをしていました。

var customer = new Customer(); //no Id yet;
var order = new Order(); //requires Customer.Id to link it to customer;
context.Customers.Add(customer);
context.SaveChanges();//this generates the Id for customer
order.CustomerId = customer.Id;//finally I can set the Id

ただし、私の場合はcustomer.Idとorder.CustomerIdの間に外部キーの関係があるため、これは必要ありませんでした。

私がしなければならなかったのはこれだけでした。

var customer = new Customer(); //no Id yet;
var order = new Order{Customer = customer}; 
context.SaveChanges();//adds customer.Id to customer and the correct CustomerId to order

変更を保存すると、顧客用に生成されたIDも注文に追加されます。追加の手順は必要ありません

これは元の質問には答えないことを承知していますが、EFに慣れていない開発者が必要ではないかもしれないものに対してトップ投票の答えを使いすぎないようにするのに役立つかもしれないと思いました。

92
mark_h

変更を保存した後にエンティティをリロードする必要があります。 EFでは追跡できないデータベーストリガーによって変更されているからです。 SO DBからエンティティを再度リロードする必要があります。

db.Entry(MyNewObject).GetDatabaseValues();

それから

int id = myNewObject.Id;

以下の質問で@jayanthaの回答を見てください。

defaultValueを使用するときにEntity Frameworkで挿入されたエンティティのIDを取得する方法

以下の質問で@christianの回答を見ても役に立ちます。

Entity Framework Refresh context?

27
QMaster

このリンクを参照してください。

http://www.ladislavmrnka.com/2011/03/the-bug-in-storegeneratedpattern-fixed-in-vs-2010-sp1/

StoreGeneratedPatternのプロパティをidentityに設定してから、独自のコードを試す必要があります。

それ以外の場合はこれを使用することもできます。

using (var context = new MyContext())
{
  context.MyEntities.AddObject(myNewObject);
  context.SaveChanges();

  int id = myNewObject.Id; // Your Identity column ID
}
16
Azhar Mansuri

データベースに変更を反映した後、保存しているオブジェクトは正しいIdを持つはずです。

11
Snowbear
Repository.addorupdate(entity, entity.id);
Repository.savechanges();
Var id = entity.id;

これはうまくいくでしょう。

6
Saket Choubey

保存後にのみIDを取得できますが、代わりに新しいGuidを作成して保存前に割り当てることができます。

私はデータベースにデータを挿入する必要があり、同時にエンティティフレームワークを使用してプライマリIDを必要とする状況に出くわしました。解決策:

long id;
IGenericQueryRepository<myentityclass, Entityname> InfoBase = null;
try
 {
    InfoBase = new GenericQueryRepository<myentityclass, Entityname>();
    InfoBase.Add(generalinfo);
    InfoBase.Context.SaveChanges();
    id = entityclassobj.ID;
    return id;
 }
4
Mr Kunal

すべての答えはそれぞれのシナリオに非常に適しています。異なる点は、Add()がint変数に返したobject(TEntity)から直接int PKを割り当てたことです。

using (Entities entities = new Entities())
{
      int employeeId = entities.Employee.Add(new Employee
                        {
                            EmployeeName = employeeComplexModel.EmployeeName,
                            EmployeeCreatedDate = DateTime.Now,
                            EmployeeUpdatedDate = DateTime.Now,
                            EmployeeStatus = true
                        }).EmployeeId;

      //...use id for other work
}

そのため、新しいオブジェクト全体を作成するのではなく、必要なものだけを使用できます。

編集@GertArnold:

enter image description here

2
IteratioN7T

2つの戦略があります。

  1. データベース生成のIDintまたはGUID)を使用する

    短所:

    保存したエンティティのIDを取得するには、SaveChanges()を実行する必要があります。

    長所:

    intアイデンティティーを使用できます。

  2. クライアント生成のID - GUIDのみを使用してください。

    長所:SaveChanges操作の縮小。 1回の操作で新しいオブジェクトの大きなグラフを挿入できるようになりました。

    短所:

    GUIDに対してのみ許可されています

2

EF 6.xコードを最初に使用するとき

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

データベーステーブルを初期化すると、

(newsequentialid())

テーブルのプロパティ内で、ヘッダーのDefault ValueまたはBindingの下にあり、IDが挿入されたときにIDを設定できます。

問題は、テーブルを作成して

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

後で説明しますが、将来のアップデートデータベースでは(newsequentialid())が追加されることはありません。

正しい方法を修正するには、移行を抹消し、データベースを削除してから再移行します。あるいは、テーブルデザイナーに(newsequentialid())を追加するだけです。

1
Jeff Li