尝试使用 Linq to SQL 来完成我在家进行的一个小项目。我已经使用 dbmetal.exe(来自 DBLinq 项目)针对本地 MySQL 数据库生成了上下文代码和所有实体类。
一切都运行良好,但我正在尝试抽象一些冗余代码,并且在尝试这样做时遇到了问题。
基本上我所有的实体都是 Table<TEntity>
类型在我的上下文类(class)中。例如我有 Table<User>
和Table<Calendar>
。
当我为存储库行为构建各种接口(interface)时,我意识到有些方法对于每个实体来说都是非常冗余的。例如ID字段:
User findById(int id);
Calendar findById(int id);
我设计了我的表,因此它们都有 3 个共同字段 [ID、DATECREATED、DATEUPDATED]。由于这些字段很常见,我希望有一个通用的行为,而不是为每个实体重写这些方法。
所以我让我的存储库类(UserRepository、CalendarRepository)继承一个通用的“Repository”类,其定义如下:
public class Repository<T> : IDisposable, IRepository<T> where T : class
{
protected MyContext context;
private DbLinq.Data.Linq.Table<T> currentTable;
protected Repository() {
context = new MyContext();
Type currentType = this.GetType().GetGenericArguments()[0];
currentTable = //Set currentTable based on currentType. e.g.: currentTable = context.User;
}
#region IRepository<T> Members
public T findById(int? id)
{
return currentTable.SingleOrDefault(d => d.ID == id);
}
public T findByDateCreated(DateTime dateCreated)
{
return currentTable.SingleOrDefault(d => DateTime.Equals(dateCreated, d.DateCreated));
}
public T findByDateUpdated(DateTime dateUpdated)
{
return currentTable.SingleOrDefault(d => DateTime.Equals(dateUpdated, d.DateUpdated));
}
public T insert(T domainObject)
{
currentTable.InsertOnSubmit(domainObject);
return domainObject;
}
public T save(T domainObject)
{
context.SubmitChanges();
return domainObject;
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (context != null)
context.Dispose();
}
#endregion
}
事实证明这比我想象的要困难。当我尝试设置时:
currentTable = (Table<T>)context.User;
我收到以下错误:
Cannot convert type 'DbLinq.Data.Linq.Table<Models.Domain.User>' to 'DbLinq.Data.Linq.Table<T>'
隐式转换也不起作用。
有人曾经成功做过类似的事情吗?如果我必须让所有存储库类都实现相同的 findById 方法,其中包含完全相同的代码,那将是非常可悲的...我确信有一种方法可以不这样做,我只是找不到它。 :)
最佳答案
That'd be very sad if I had to have all my Repository classes implement the same findById method with exactly the same code in it
代码并不完全相同。在每种情况下,您都在上下文中引用不同的表。
我理解你的逻辑;你想要干燥。但拥有存储库的原因是让您能够通过注入(inject)模拟存储库而不是真实存储库来抽象数据访问逻辑,以促进单元测试。最实用(且灵活)的方法是保持表(和 DAL 对象)独立且不同。通过尝试泛化部分 DAL 对象,您将引入额外的耦合,这将使单元测试变得复杂。
关于c# - 通用表<TEntity>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1694851/