EntityFramework按ID获取对象?

Jam*_*ght 26 c# linq asp.net reflection entity-framework

Generics是否可以在不知道类型的情况下从我的EntityFramework中获取对象?

我正在考虑以下方面的事情:

public T GetObjectByID<T>(int id)
{
   return (from i in myDatabase.T where i.ID == id select i);
}
Run Code Online (Sandbox Code Playgroud)

那可行吗?我可以使用Reflection以某种方式将T.GetType().Name其用于表中吗?

编辑
另一个问题是,并非所有可用的表都使用"ID"作为其唯一的列名.

Lad*_*nka 31

您可以定义所有实体实现的接口:

public interface IEntity
{
    int Id { get; }
}
Run Code Online (Sandbox Code Playgroud)

和检索实体的方法:

public T GetObjectById<T>(int id) where T : class, IEntity
{
    return context.CreateObjectSet<T>().SingleOrDefault(e => e.Id == id);
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用与链接问题中提供的方法类似的方法.您只需使用另一种方法来获取您的实体:

public virtual T GetByKey<T>(int id) where T : class, IEntity
{
     string containerName = context.DefaultContainerName;
     string setName = context.CreateObjectSet<T>().EntitySet.Name;
     // Build entity key
     var entityKey = new EntityKey(containerName + "." + setName, "Id", id);
     return (TEntity)Context.GetObjectByKey(entityKey);         
}
Run Code Online (Sandbox Code Playgroud)

不同之处在于,即使您已将实例加载到上下文,第一种方法也始终查询数据库,而第二种方法首先检查实例是否已加载.该方法效率不高,因为它反复构建这些名称.是更通用的方法,可以使用任何键类型和名称,这里是使用复杂键的方法.

这种方法都不能直接用于继承 - 您必须提供基本类型才能使其工作.


Yuc*_*uck 27

我认为该Find()方法可能能够做你想要的(DbSet.Find方法).

var someEntity = dbSet.Find(keyValue);
Run Code Online (Sandbox Code Playgroud)


Kir*_*rst 5

很难创建一个完全通用的解决方案,因为实体可以有复合键,但这适用于简单的单键案例.

关键是限制T为类型System.Data.Objects.DataClasses.EntityObject,然后具有EntityKey属性(表示主键).

static T GetById<T>(object id) where T : EntityObject
{
    using (var context = new MyEntities())
    {
        return context.CreateObjectSet<T>()
            .SingleOrDefault(t => t.EntityKey.EntityKeyValues[0].Value == id);
    }
}
Run Code Online (Sandbox Code Playgroud)


Jam*_*ght 3

最终解决了这个问题: http:
//pastebin.com/kjXUKBNS

要调用代码,我使用以下代码:

// Get the id of the object we are saving
PropertyInfo prop = GetProperty<TEntity>(entity, entity.EntityKey.EntityKeyValues[0].Key);
string entityID = prop.GetValue(entity, null).ToString();

// Get the current version of this object
var originalEntity = GetEntity<TEntity>(PropertyEquals, entityID);
Run Code Online (Sandbox Code Playgroud)

这假设您正在搜索的主键是主键列表中的第一个。

  • 这是一个非常丑陋的解决方案,因为它使用反射,并且该解决方案与您的问题不符 - 如果您的初始示例知道 Id,为什么还要提取值?您是否再次检查过其他人提供的链接?@Yuck 在他的评论中链接了这个问题的更好解决方案。 (6认同)