迄今为止的故事......
我现在正在学习 MVC(4)。我已经编写了充满控制器膨胀的应用程序,所以我决定开始添加存储库/UnitOfWork/服务层等。
所以我决定创建一个通用存储库来封装一般的 CRUD 和记录搜索功能。
“停止喋喋不休,你有什么问题”我听到你说
我想我会创建一个Get方法,它需要两个 Lambda 参数:
- filter = 选择/取消选择记录逻辑
- singleOrDefault = 根据参数提供一条记录或默认值。
以下是包含 get 方法的精简Generic Repository代码:
public class GenericRepository<TEntity> :
IRepository<TEntity> where TEntity : class
{
internal AccountsContext context;
internal DbSet<TEntity> dbSet;
/// <summary>
/// Default Constructor.
/// </summary>
/// <param name="context"></param>
public GenericRepository(AccountsContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter,
Expression<Func<TEntity, bool>> singleOrDefault)
{
IQueryable<TEntity> query = dbSet;
if (filter != null && singleOrDefault == null)
{
query = query.Where(filter);
}
if (filter != null && singleOrDefault != null)
{
query = query.Where(filter)
.SingleOrDefault(singleOrDefault);
}
return query.ToList();
}
现在,当我尝试构建这个时,下面的编译器:
错误 1 无法将类型“TEntity”隐式转换为“System.Linq.IQueryable”。存在显式转换(您是否缺少演员表?) G:\Accountable\Accountable\DataAccessLayer\GenericRepository.cs 90 30 Accountable
错误位于.SingleOrDefault(singleOrDefault)行。
为了您的方便,我提供了我使用的扩展方法签名:
public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
public static TSource SingleOrDefault<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
我多年来一直在盯着这个问题试图解决它,任何帮助将不胜感激。
供参考
在我臃肿的代码中,我的控制器中有以下类型的代码,我想用我的存储库方法替换它们,这就是我试图复制的内容。
LedgerCustomer LedgerCustomer = db.LedgerCustomers.Where(l => l.RecordStatus != "X").SingleOrDefault(l => l.id == id);
CurrencyType currencyType = db.CurrencyTypes.Where(c => c.RecordStatus != "X")
.SingleOrDefault(c => c.id == LedgerCustomer.CurrencyTypeId);
问题是:
A)我使用正确的 LINQ 方法吗?我臃肿的代码中的上述查询是:
选择 RecordStatus 不等于 X(逻辑删除)且 id 等于特定 id 的 Ledger customer。
因为 LedgerCustomer PER id 应该只有一条记录(因为它们是唯一的,所以我使用 SingleOrDefault 和 Where 来取消选择任何逻辑删除的 LedgerCustomer。
B)有关编译器错误的帮助会有所帮助。