如何在C#中访问泛型类型的元素

时间:2012-05-13 14:17:10

标签: c# entity-framework entity-framework-4

我正在开发一个可重用的数据库存储库方法,用于使用EntityFramework 4.3将实体附加和保存到数据库。

    private void SaveObject<T>(T entityToSave, DbSet<T> dbSet) where T : class
    {
        if (db.Entry(entityToSave).State == EntityState.Detached)
        {
            if (entityToSave.Id == Guid.Empty) // how do I access the Id property?
                dbSet.Add(entityToSave);
            else
                db.Entry(entityToSave).State = EntityState.Modified;
        }
    } 

我遇到的问题是我需要告诉我的方法哪个属性是Id,所以我可以检查它是否已设置。如果它是空的,那么我知道我正在创造一个全新的记录。否则我正在修改现有记录。

如何告诉我的方法Id属性是什么?

3 个答案:

答案 0 :(得分:3)

您需要创建一个包含Id属性的接口。

让所有实体类实现此接口并约束T来实现它。 (where T : IHasId
然后,您将能够在方法中访问此界面的所有成员。

答案 1 :(得分:3)

您需要一个定义Id属性的接口或基类,并将其用作通用约束。例如:

public interface IEntity
{
    Guid Id { get; }
}

private void SaveObject<T>(T entityToSave, DbSet<T> dbSet) where T : class, IEntity
    {
        if (db.Entry(entityToSave).State == EntityState.Detached)
        {
            if (entityToSave.Id == Guid.Empty) // how do I access the Id property?
                dbSet.Add(entityToSave);
            else
                db.Entry(entityToSave).State = EntityState.Modified;
        }
    } 

答案 2 :(得分:1)

正如其他人所示,您可以使用界面解决问题。另一种可能性是定义一个访问者代表

private void SaveObject<T>(T entityToSave, DbSet<T> dbSet, Func<T,Guid> accessId)
{
    ...
    Guid id = accessId(entityToSave);
    ...
}

打电话
SaveObject(entityToSave, dbSet, e => e.Id)
SaveObject(otherEntityToSave, dbSet, e => e.UserID)

优于接口的优点是,id可以具有不同的名称,并且与第二个通用参数一起使用,甚至可以使用不同的类型

private void SaveObject<T,I>(T entityToSave, DbSet<T> dbSet, Func<T,I> accessId)
{
    ...
    I id = accessId(entityToSave);
    ...
}