【发布时间】:2014-07-08 08:16:38
【问题描述】:
我正在使用带有大型数据库(由 200 多个表组成)的实体框架。
尝试创建一个泛型方法,该方法返回特定表T(即类,可以是TableA)的DbSet<T>。
使用实体数据模型(自动)创建的实体类如下所示:
public partial class sqlEntities : DbContext
{
public virtual DbSet<TableA> TableA { get; set; }
public virtual DbSet<TableB> TableB { get; set; }
public virtual DbSet<TableC> TableC { get; set; }
... // other methods
}
我的主班是这样的
public class TableModifier
{
// Should return first 10 elements from a table of that type T
public IQueryable<T> GetFromDatabase<T>() where T : EntityObject
{
try
{
using (sqlEntities ctx = new sqlEntities())
{
// Get the DbSet of the type T from the entities model (i.e. DB)
DbSet<T> dbSet = ctx.Set<T>();
return dbSet.Take(10);
}
}
catch (Exception ex)
{
// Invalid type was provided (i.e. table does not exist in database)
throw new ArgumentException("Invalid Entity", ex);
}
}
... // other methods
}
我必须在T 上设置一个约束where T : EntityObject,使其在EntityObject 范围内。如果没有这样的约束,那么DbSet<T> dbSet 会抱怨(即T 必须是引用类型)它可能会在类型方面得到比预期更多的东西(based 对此)。
当我尝试实际调用具有特定类型的方法时会出现问题。
[TestMethod]
public void Test_GetTest()
{
TableModifier t_modifier = new TableModifier();
// The get method now only accepts types of type EntityObject
IQueryable<TableA> i_q = t_modifier.GetFromDatabase<TableA>();
}
它给出了一个错误:
There is no implicit reference conversion from 'TableMod.TableA' to
'System.Data.Entity.Core.Objects.DataClasses.EntityObject'.
如果我知道该实体模型存在 TableA 类型,我如何(转换?)为 EntityObject?
虽然这是不正确的语法(和逻辑),但这是我所追求的:
t_modifier.GetFromDatabase<(EntityObject)TableA>();
如何将TableA(以及所有其他200 个表)类型定义为EntityObject 的一部分?
一个潜在的解决方案
原来我的约束太具体了,我需要改变的只是从where T : IEntity 到
where T : class
所以T 是DbSet<T> 最初期望的,一个类类型
省去了向 200 多个表类添加实现的麻烦,TableA、TableB、...
当然还有其他问题,例如将返回类型从IQueryable<T> 更改为List<T>,因为IQueryable 将在DbContext 的范围之外返回(即sqlEntities)使其无用。
【问题讨论】:
-
你想测试什么?
-
猜测
TableMod.TableA不继承自EntityObject? -
您可能针对的 EF 版本不再要求所有实体类型都派生自
EntityObject。使用where T : class足以满足您的目的。没有必要仅仅为了适应您正在编写的这个 new 方法而更改现有类型的继承映射。
标签: c# entity-framework generics