如何在Entity框架中获取插入实体的Id?

时间:2011-03-06 19:11:10

标签: c# entity-framework entity

我在Asp.net中遇到了Entity Framework的问题。每当我将对象添加到数据库时,我想获取Id值。我怎么能这样做?

11 个答案:

答案 0 :(得分:878)

这很容易。如果您正在使用数据库生成的ID(如MS SQL中的IDENTITY),则只需在相关的ObjectSet上将实体添加到SaveChangesObjectContext。系统会自动为您填写Id

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

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

当使用自动生成的INSERT时,默认情况下,每个SELECT SCOPE_IDENTITY() Id跟随实体框架。

答案 1 :(得分:92)

我在使用实体框架时一直使用Ladislav Mrnka's answer来成功检索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新手的开发人员过度使用最高投票的答案,而这些答案可能并不是必需的。

答案 2 :(得分:27)

您需要在保存更改后重新加载实体。因为它已被EF无法跟踪的数据库触发器更改。所以我们需要再次从数据库重新加载实体,

db.Entry(MyNewObject).GetDatabaseValues();

然后

int id = myNewObject.Id;

在下面的问题中查看@jayantha答案:

How can I get Id of the inserted entity in Entity framework when using defaultValue?

在下面的问题中查看@christian答案也可能有所帮助:

Entity Framework Refresh context?

答案 3 :(得分:16)

请参阅此链接。

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
}

答案 4 :(得分:11)

在将更改传播到数据库之后,您要保存的对象应该具有正确的Id

答案 5 :(得分:6)

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

这样可行。

答案 6 :(得分:5)

您只能在保存后获取ID,而是可以在保存之前创建新的Guid并进行分配。

答案 7 :(得分:4)

我遇到过需要在数据库中插入数据的情况。同时要求使用实体框架的主要ID。 解决方案:

{{1}}

答案 8 :(得分:2)

有两种策略:

  1. 使用数据库生成的IDintGUID

    缺点:

    您应该执行SaveChanges()来获取刚刚保存的实体的ID

    优点:

    可以使用int身份。

  2. 使用客户端生成的ID-仅GUID。

    优点: 缩小SaveChanges个操作。 能够在每个操作中插入一个新对象的大图。

    缺点:

    仅允许GUID

答案 9 :(得分:2)

所有答案都非常适合他们自己的情况,我所做的不同是我直接从Add()返回给这样的int变量的对象(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

答案 10 :(得分:1)

首次使用EF 6.x代码时

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

并初始化一个数据库表,它会放一个

(newsequentialid())

在标题Default Value或Binding下的表属性中,允许在插入ID时填充ID。

问题是如果您创建一个表并添加

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

部分之后,未来的更新数据库不会再添加(newsequentialid())

修复正确的方法是擦除迁移,删除数据库并重新迁移...或者您只需将(newsequentialid())添加到表设计器中。