我在Asp.net中遇到了Entity Framework的问题。每当我将对象添加到数据库时,我想获取Id值。我怎么能这样做?
答案 0 :(得分:878)
这很容易。如果您正在使用数据库生成的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
时,默认情况下,每个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答案也可能有所帮助:
答案 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)
有两种策略:
使用数据库生成的ID
(int
或GUID
)
缺点:
您应该执行SaveChanges()
来获取刚刚保存的实体的ID
。
优点:
可以使用int
身份。
使用客户端生成的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先生:
答案 10 :(得分:1)
首次使用EF 6.x代码时
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
并初始化一个数据库表,它会放一个
(newsequentialid())
在标题Default Value或Binding下的表属性中,允许在插入ID时填充ID。
问题是如果您创建一个表并添加
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
部分之后,未来的更新数据库不会再添加(newsequentialid())
修复正确的方法是擦除迁移,删除数据库并重新迁移...或者您只需将(newsequentialid())添加到表设计器中。