如何在我自己的通用接口/类

时间:2016-09-03 22:03:13

标签: c# generics lambda wrapping

我在解决通用实现中的问题时遇到了一些问题。

首先,我想要完成的事情

我试图实现自己的存储库(以及后来我的UoW),为此我已经

This classes, see the diagram

那么,问题是什么?

在我的IRepository中我是这样的:

public interface IRepository<T> where T : class
{
    List<T> GetAll();
    /* some other methods*/

    //Here is my problem
    DbQuery<T> Include<T, U>(Expression<Func<T, U>> path);
}

在我的班上我有这个:

public class Repository<T> : IRepository<T> where T : class
{
    protected readonly MyDBContext context = null;

    protected DbSet<T> DbSet { get; set; }

    #region Constructors
       public Repository()
       {
           context = new MyDBContext();
           DbSet = context.Set<T>();
       }

       public Repository(MyDBContext context)
       {
           this.context = context;
       }
    #endregion

    public List<T> GetAll()
    {
        return DbSet.ToList();
    }

    /* more code for the rest of methods*/

    //And here is my problem
    DbQuery<T> Include<T, U>(Expression<Func<T, U>> path) where U : class
    {
        return (DbSet<T>)DbSet.Include(path);
    }
}

因此,我尝试在界面中以不同的方式定义此方法,但我使用的方法似乎是 - 至少 - 正确定义方法的方法。但在实施过程中我遇到了错误:

&#34;最好的超载巧合有一些无效的论据&#34;

我尝试删除方法定义中的T,U

DbQuery<T> Include(Expression<Func<T, U>> path)

然后我无法指定U和我的错误:

&#34;无法找到U的类型或命名空间,您是否缺少指令?&#34;

如果我这样做:

DbQuery<T> Include(Expression<Func<T, T>> path) 

我没有任何错误,但是错过了使用不同类别的lambda的观点

我也有错误,比如内部和外部定义中的T是相同的

后面的想法是这个存储库应该用于定义MyRepository,如:

public class MyClassRepository : Repository<MyClass>, IMyClassRepository

然后将在控制器中使用,如:

MyClassRepository repo = new MyClassRepository();

然后:

repo.Include(o => o.MyOtherClass);

现在我已经解决了这个问题,在界面中定义了一个不同的方法

IQueryable<T> Include(string path)

并实施为:

public IQueryable<T> Include(string path)
{
    return DbSet.Include(path);
}

然后在我的控制器中我会像这样使用:

repo.Include("MyOtherClass");

这不是很糟糕但我失去了lambda能力。

所以,如果有人发现我失踪的东西,我将非常感激。

谢谢大家

加布里埃尔

1 个答案:

答案 0 :(得分:1)

从Include方法中删除泛型T声明,因为您已经在类级别定义了它。

DbQuery<T> Include<U>(Expression<Func<T, U>> path);

不要忘记在实现中公开方法并删除U约束,因为它们不会出现在界面中。

作为旁注,IDbSet已经是一个存储库,而DbContext已经是一个UoW。 IDbSet让您认为您正在使用内存中的实体集合,并DbContext跟踪其IDbSets中所做的更改,并为您提供了一种在完成后提交这些更改的方法。