EF Generic Repository 从新插入的通用实体获取 Id
Posted
技术标签:
【中文标题】EF Generic Repository 从新插入的通用实体获取 Id【英文标题】:EF Generic Repository get Id from new inserted generic entity 【发布时间】:2010-08-23 13:23:13 【问题描述】:我所有的实体都有属性 ID。我在数据库中的所有表都具有自动生成的整数标识 ID 作为主键。
我有创建实体的通用方法。
实体插入数据库后,有什么方法可以获取实体ID?
public override int Create<T>(T entity)
string entitySet = GetEntitySetName<T>();
_context.AddObject(entitySet, entity);
_context.SaveChanges();
return <Id Here>; //TODO Return Id here
在简单(非通用)存储库中,我可能只返回 Entity.Id,但如何在通用存储库中获得相同的行为? 我可能有所有包含 int 属性 Id 的实体的基实体类,但有没有办法在不实现此继承的情况下使其工作?
【问题讨论】:
【参考方案1】:这实际上非常简单;
// Project is is object/table, no POCO here.
var newProj = new Project();
newProj.Name = "Blah project";
var db = new AppDataContextname();
db.Projects.AddObject(newProj);
// at this point, newProj.ID is NOT set
db.SaveChanges(); // record is added to db.
// now, the ID property of the Project object is set!!!
// if the last ID in that table is '25', and you have auto-increment,
// then the object's ID property will now be 26!
Console.WriteLine(newProj.ID); // will output "26"
我绞尽脑汁想如何找回 ID 很长时间,直到我意识到上面的代码有效。适用于 Linq-To-SQL 和 EF4。
【讨论】:
【参考方案2】:对于 POCO 实体,您必须使用接口、反射或 dynamic
。
使用EntityObject
实体,您可以读取EntityKey
属性。
【讨论】:
谢谢,界面是更好的方式,但暂时我会选择动态的。 '动态 currentEntity = 实体;' '返回 currentEntity.Id;'【参考方案3】:解决办法:
public override TR Create<T, TR>(T entity)
string entitySet = GetEntitySetName<T>();
_context.AddObject(entitySet, entity);
_context.SaveChanges();
//Returns primaryKey value
return (TR)context.CreateEntityKey(entitySet, entity).EntityKeyValues[0].Value;
其中T:实体类型,TR:实体PK类型。
【讨论】:
是否可以在调用 savechanges 之前获取 id? @Jeroen 有两种方法可以做到这一点,如果你想在这种情况下使用 int 作为 PK 首先你需要插入空记录来获取数据库生成的新 Id,否则你可以使用 Guid 作为PK,在这种情况下,您可以通过调用 Guid.NewGuid() 在代码中直接生成 PK 请说明如何调用您的Create()
函数,该函数将返回PK 值。谢谢【参考方案4】:
With reflection you can obtain the Id property.
public override int Create<T>(T entity)
string entitySet = GetEntitySetName<T>();
_context.AddObject(entitySet, entity);
_context.SaveChanges();
var idProperty = item.GetType().GetProperty("Id").GetValue(entity,null);
return (int)idProperty;
【讨论】:
这行得通,但它可能会拖累性能.. 反射很慢(很多人认为)。以上是关于EF Generic Repository 从新插入的通用实体获取 Id的主要内容,如果未能解决你的问题,请参考以下文章
Generic repository pattern and Unit of work with Entity framework
无法将类型“IQueryable”隐式转换为 Generic.IList' 从 EF 上下文中检索记录列表作为列表