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的主要内容,如果未能解决你的问题,请参考以下文章

EF Repository Update

Generic repository pattern and Unit of work with Entity framework

无法将类型“IQueryable”隐式转换为 Generic.IList' 从 EF 上下文中检索记录列表作为列表

您如何处理仅使用 EF4 plus Repository Pattern 显示视图的应用程序?

EXCEL表格如何在EF间插入一列新表格?

ABP CORE+EF 批量删除修改