包括泛型类型参数

时间:2012-12-17 03:55:16

标签: c# entity-framework generics typeof

我正在编写一些BLL代码,以便位于Entity框架之上(使用DBContext生成的DAL类,但这与此问题无关)。这是我的一个惯例:

public static Customer Get(int32 CustID, IEnumerable<string> IncludeEntities = null)
{
}

所以当我调用它时,我会传递一个CustID,一个我希望包含的实体的可选列表 - 例如“Orders”和“OrderDetails”:

Customer customer = CustomerBLLRepository.Get("ALFKI", 
     new[] { "Orders", "Orders.Order_Details"});

它工作正常,但我不喜欢用列表或字符串数​​组调用它 - 我希望得到强类型,以便IDE可以提供帮助。

我可以通过这样声明来接收类型列表:

public static void GetTest(Int32 CustID, params Type[] IncludeEntities)
{
}

并将类名称作为字符串以使包含起作用,但调用者必须使用这样的typeofs:

CustomerRepository.GetTest(123, typeof(Order), typeof(OrderDetails));

这不是世界末日,但这会导致问题,因为OrderDetails实际上是Orders的导航属性,而include需要被称为Orders.OrderDetails,我必须让代码四处寻找子节点中的哪个实体OrderDetails仍然生成字符串。

我真正想要的是一个强类型的实体列表要传递,因为包含的格式相同,EF希望它们包含但是我认为我是SOL。

2 个答案:

答案 0 :(得分:1)

假设您的EF模型保持关系 为什么不使用带有Lambda的Custom Get Routine。 根据您的样本,您将获得“客户”。

public class RepositoryCustomer: RepositoryBase<Customer> 
...
...
public class RepositoryEntityBase<T>
   public virtual T Get(Expression<Func<T, bool>> predicate)
       return Context.Set<T>.Where(predicate).FirstOrDefault();

您可以在上下文中调用任何集合的Generic Get例程,

var aCustomer = RepositoryCustomer.Get(c=>c.id=="ALFKI" && c.Orders.OrderDetail=="bla")

虚拟导航属性非常有用且灵活。

答案 1 :(得分:0)

确定要包含在查询中的实体不应该是除BLL之外的任何任务。如果BLL获取了一个属性或多个属性,这些属性引用了数据存储的结构,那么您就是在说BLL需要知道的有关数据存储内部结构的任何调用。编辑:不够清楚。这样做是完全错误的。

IMO你应该为每个用例创建一个单独的方法 - 否则你的BLL只是DAL的帮助方法,并且没有责任分离关注点。

这是实体框架的一个主要问题 - MS似乎应该将您的查询放在任何您喜欢的位置,并使用并保持实体在任何您喜欢的地方存活。确实很难看到光明。