1

迄今为止的故事......

我现在正在学习 MVC(4)。我已经编写了充满控制器膨胀的应用程序,所以我决定开始添加存储库/UnitOfWork/服务层等。

所以我决定创建一个通用存储库来封装一般的 CRUD 和记录搜索功能。

“停止喋喋不休,你有什么问题”我听到你说

我想我会创建一个Get方法,它需要两个 Lambda 参数:

  1. filter = 选择/取消选择记录逻辑
  2. 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)有关编译器错误的帮助会有所帮助。

4

1 回答 1

2

问题出在(如您所料)就行了;

query = query.Where(filter).SingleOrDefault(singleOrDefault);

query是一个 IQueryable,所以Where(filter).SingleOrDefault(singleOrDefault)在它上面使用是可以的。

问题在于您试图将返回的结果分配SingleOrDefaultquery.
SingleOrDefault不返回 IQueryable,而是仅返回TEntity.

于 2012-09-23T11:45:12.530 回答