我真的很困惑。你能帮我么?见代码;
我正在尝试为我的解决方案构建一个只使用一个存储库的结构。要查询特定查询,我使用IQueryBuilder。实际上我正在寻找对象查询的好东西,我找到了这个here
public interface IQueryBuilder<T> where T : class
{
IQueryBuilder<T> Where(Expression<Func<T, bool>> predicate);
IQueryBuilder<T> Include(Expression<Func<T, object>> path);
IQueryBuilder<T> OrderBy(Expression<Func<T, object>> path);
IQueryBuilder<T> OrderByDescending(Expression<Func<T, object>> path);
IQueryBuilder<T> Page(int page, int pageSize);
T FirstOrDefault();
Task<T> FirstOrDefaultAsync();
List<T> ToList();
Task<List<T>> ToListAsync();
int Count();
Task<int> CountAsync();
}
此处的存储库代码。
public interface IRepository<T> : IDisposable
{
IQueryBuilder<T> Query<T>() where T : class;
}
到目前为止对我这么好。在按F6之前我非常高兴,因为存储库界面中的Query,我得到以下错误。
警告1类型参数“T”与外部类型“IRepository”中的类型参数同名IRepository.cs 13 32 VideoK2.Repository
顺便提一下这个话题有几个问题。但我无法理解他们。无法弄清楚我的话题。所以,抱歉再次询问。
答案 0 :(得分:9)
编译器认为此定义不明确:
public interface IRepository<T> : IDisposable
{
IQueryBuilder<T> Query<T>() where T : class;
}
要了解原因,请问自己这个示例问题(我将使用两个随机选择的类):如果您有一个IRepository<string>
的实例,您是否可以在其上调用Query<StreamReader>
?< / p>
如果答案是肯定的,这意味着方法T
的类型参数Query<T>
与接口T
的类型参数IRepository<T>
不同。它们是两个独立的类型参数。如果是这种情况,那么只需将其中一个更改为其他内容,以明确您的意图:
public interface IRepository<T> : IDisposable
{
IQueryBuilder<TResult> Query<TResult>() where TResult : class;
}
如果答案为否,则表示接口T
的类型参数IRepository<T>
指示方法Query
的返回类型。如果是这种情况,那么该方法不应声明自己的类型参数,因为该类型已经具有该信息。
public interface IRepository<T> : IDisposable
where T : class
{
IQueryBuilder<T> Query();
}
答案 1 :(得分:5)
此代码:
public interface IRepository<T> : IDisposable
{
IQueryBuilder<T> Query<T>() where T : class;
}
基本上可以改写为:
public interface IRepository<TObject> : IDisposable
{
IQueryBuilder<TResult> Query<TResult>() where TResult : class;
}
摆脱错误。问题是第二个<T>
影响第一个。
但是...... 你看到这个新代码的问题了吗?
我猜你的真正含义是:
public interface IRepository<T> : IDisposable
where T : class
{
IQueryBuilder<T> Query();
}
或者这个:
public interface IRepository : IDisposable
{
IQueryBuilder<T> Query<T>() where T : class;
}
保留这两个通用参数在这种情况下没有多大意义,因为其中一个从未使用过。
答案 2 :(得分:0)
好。答案后,我看到了正确的方法。我使用Generic Repository和Object Query的原因是我想为所有查询使用一个存储库。所以这迫使我使用Generic Repository。 (因为我以前的练习)。但在此示例中,不需要使用通用存储库。
我想写一些代码以获取更多信息。
此对象查询的接口
public interface IQueryBuilder<T>
{
IQueryBuilder<T> Where(Expression<Func<T, bool>> predicate);
IQueryBuilder<T> Include(Expression<Func<T, object>> path);
IQueryBuilder<T> OrderBy(Expression<Func<T, object>> path);
IQueryBuilder<T> OrderByDescending(Expression<Func<T, object>> path);
IQueryBuilder<T> Page(int page, int pageSize);
T FirstOrDefault();
Task<T> FirstOrDefaultAsync();
List<T> ToList();
Task<List<T>> ToListAsync();
int Count();
Task<int> CountAsync();
}
及其实施
public class QueryBuilder<T> : IQueryBuilder<T>
{
DdContext applicationDbContext;
private IQueryable<T> query;
public QueryBuilder(DbContext applicationDbContext)
{
this.applicationDbContext = applicationDbContext;
this.query = this.context.Set<T>();
}
public IQueryBuilder<T> Where(Expression<Func<T, bool>> predicate)
{
this.query = this.query.Where(predicate);
return this;
}
public IQueryBuilder<T> Include(Expression<Func<T, object>> path)
{
this.query = this.query.Include(path);
return this;
}
public IQueryBuilder<T> OrderBy(Expression<Func<T, object>> path)
{
this.query = this.query.OrderBy(path);
return this;
}
public IQueryBuilder<T> OrderByDescending(Expression<Func<T, object>> path)
{
this.query = this.query.OrderByDescending(path);
return this;
}
public IQueryBuilder<T> Page(int page, int pageSize)
{
this.query = this.query.Skip(page * pageSize).Take(pageSize);
return this;
}
public T FirstOrDefault()
{
return this.query.FirstOrDefault<T>();
}
public Task<T> FirstOrDefaultAsync()
{
return this.query.FirstOrDefaultAsync();
}
public List<T> ToList()
{
return this.query.ToList();
}
public Task<List<T>> ToListAsync()
{
return this.query.ToListAsync();
}
public int Count()
{
return this.query.Count();
}
public Task<int> CountAsync()
{
return this.query.CountAsync();
}
}
这是Repository接口
public interface IRepository
{
IQueryBuilder<T> Query<T>();
}
及其实施
public class Repository : IRepository
{
private DBContext Contex { get; set; }
public Repository(DBContext ctx)
{
this.Contex = ctx;
}
public QueryBuilder.IQueryBuilder<T> Query<T>()
{
return new QueryBuilder.QueryBuilder<T>(this.Contex);
}
}
这些行是样本用法
public class HomeController : Controller
{
private IRepository repo = new Repository(new SampleContext());
public HomeController(){}
// GET: Home
public ActionResult Index()
{
var author = repo.Query<Author>().ToList();
var authors = repo.Query<Author>().ToListAsync();
var authors = repo.Query<Author>().Where(a => a.Name != "Orwell").ToList();
var authors = repo.Query<Author>().Where(a => a.Name != "Orwell").ToListAsync();
var author = repo.Query<Author>().FirstOrDefault();
var author = repo.Query<Author>().FirstOrDefaultAsync();
var author = repo.Query<Author>().Where(a => a.Name == "Orwell").FirstOrDefault();
var author = repo.Query<Author>().Where(a => a.Name == "Orwell").FirstOrDefaultAsync();
var book = repo.Query<Book>().Where(b => b.Title == "The Wasp Factory").FirstOrDefault();
return View(author);
}
}