我正在编写通过ID获取单个实体的方法:
public Customer GetCustomer(int i_CustomerID)
{
return (from c in context.CustomerSet
where c.Id == i_CustomerID
select c).SingleOrDefault();
}
public Movie GetMovie(int i_MovieID)
{
return (from m in context.MovieSet
where m.Id == i_MovieID
select m).SingleOrDefault();
}
但我有很多实体,这段代码重复了一遍。我想写一个像这样的方法:
public T GetEntityByID<T>(int i_EntityID)
{
return (from e in context.T_Set
where e.Id == i_EntityID
select e).SingleOrDefault();
}
有没有办法实现这个目标?
答案 0 :(得分:3)
我实际上并没有执行此操作,但它编译并且可能与您要实现的内容类似:
public static void Testing()
{
SelectEntity<MyObject>(r => r.MyObjectId == 1);
}
public static T SelectEntity<T>(Expression<Func<T, bool>> expression) where T : EntityObject
{
MyContext db = new MyContext();
return db.CreateObjectSet<T>().SingleOrDefault(expression);
}
答案 1 :(得分:1)
问题在于没有常见的超类型具有您寻求的相关属性。但是,很容易使用EF正在使用的内置T4代码生成工具来生成您的获取方法。这是一个关于如何挂钩并生成所需代码的良好链接。
答案 2 :(得分:0)
如果您知道您的通用存储库将始终与具有相同名称和相同类型的PK的实体类型一起使用,您可以简单地定义这样的接口:
public interface IEntity
{
int Id { get; }
}
并在生成的实体的部分部分中实现此接口,或者修改T4模板以自动包含它。然后,您的存储库将定义为:
public interface IRepository<TEntity> where T : IEntity
{
...
}
如果PK的类型可以更改但名称仍然相同,则可以将实体界面改进为:
public interface IEntity<TKey>
{
TKey Id { get; set; }
}
并且存储库的定义将是:
public interface IRepository<TEntity, TKey> where TEntity : IEntity<TKey>
{
...
}
如果您想要能够使用具有不同PK名称和类型的实体的通用存储库,请检查this answer。该解决方案应该也可以使用复合PK工作(或进行小修改)。