Linq to SQL 中的 DAO 工厂
Posted
技术标签:
【中文标题】Linq to SQL 中的 DAO 工厂【英文标题】:Factory for DAO in Linq to SQL 【发布时间】:2012-04-19 07:28:59 【问题描述】:我正在努力创造以下情况:
首先,有几个 Linq to SQL Table 对象可以做几乎相同的事情。我们称它们为 products_something、products_somethingElse 等。
其次,有一个接口可以执行 Products DAO 的所有常用方法。首先,我尝试为所有产品只创建一个 DAO,因为我可以处理它在另一层(DAL)上的差异。但由于 Linq to SQL 需要强类型引用,我最终为每种类型的产品使用了一个 DAO。我真的不知道是否有可能做我之前提到的。
最后,我有一个 ProductsDaoFactory,它根据客户端(用户视图)选择实例化正确的 ProductDao。因为我不知道在运行时会选择哪种类型的产品,所以我创建了一个通用工厂来处理它。
代码如下:
public enum ProductEnum
SimpleProduct, ComplexProduct, RevisedProduct, BrokenProduct
public interface IProducts<T>
T GetProductById(int id);
IQueryable<T> GetAllProducts(string product_name, DateTime product_age);
//Several other common methods
public static class ProductFactory
//This won't compile because i have to set what's the type of the DAO i want
public static IProducts<T> GetProductDAO(ProductEnum product)
switch (product)
case ProductEnum.SimpleProduct:
return new SimpleProductDAO();
case ProductEnum.ComplexProduct:
return new ComplexProductDAO();
case ProductEnum.RevisedProduct:
return new RevisedProductDAO();
case ProductEnum.BrokenProduct:
return new BrokenProductDAO();
default:
break;
return null;
public class SimpleProductDAO : IProducts<SimpleProductDAO>
public SimpleProductDAO GetProductById(int id)
//Implementation
public IQueryable<SimpleProductDAO> GetAllProducts(string product_name, DateTime product_age)
//Implementation
问题是:我无法定义工厂方法的返回类型,因为它是通用的。我必须将它的类型传递给工厂,这只会打破工厂的想法。 那么,如何创建一个工厂方法来实例化接口的泛型类型?
【问题讨论】:
【参考方案1】:您的问题是您的泛型并不是真正的泛型。所以你的方法根本不应该是通用的,因为我不能说:
GetProductDAO<int>(someEnum);
我相信从工厂中删除泛型不仅可以解决问题,还可以为 API 的用户提供更好的清晰度和连贯性。 话虽如此,泛型确实可以提供更好的智能感知。
我最喜欢的解决方案将是删除枚举并只传递泛型类型,你会添加对方法的限制。
public static IProducts<T> GetProductDAO<T>() where T: ISomeMarkerInterface, new()
所以SimpleProductDAO
将实现ISomeMarkerInterface
,这只是一个空接口:
public interface ISomeMarkerInterface
工厂变小了:
public static class ProductFactory
public static IProducts<T> GetProductDAO<T>() where T : ISomeMarkerInterface, IProducts<T>, new()
return new T();
或者
这样定义工厂:
public static IProducts<T> GetProductDAO<T>(ProductEnum product)
...
这不是我最喜欢的解决方案,因为它可以不受限制地被滥用
【讨论】:
但是按照你的建议进行定义不会破坏工厂的整体理念,因为我必须知道要实例化哪种产品而不是让工厂为我做?从哪里说要删除泛型?从接口还是从工厂? 编译器由于某种原因无法识别where T: ISomeMarkerInterface, new()
。 SimpleProduct
已经在实施 ISomeMarkerInterface
。还有一件事,声明where T: ISomerMarkerInterface, new
不会导致激活器迟滞问题?
@AdrianoRR try where T: new(), ISomeMarkerInterface
new()
指令必须是最后一个约束。我相信它不会识别,因为您必须像GetProductDAO<T>
一样定义它。然而,这会导致return new T();
出现问题,因为它需要显式转换为IProduct<T>
。
忘记我之前说的话。问题是我必须在我的工厂中定义我想要实例化的产品类型(在编译器时)。我相信这打破了工厂的想法。以上是关于Linq to SQL 中的 DAO 工厂的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 LINQ to SQL 创建通用数据访问对象 (DAO) CRUD 方法