0

我试图找出一种方法将包含语句的集合传递到我的存储库中,以便我可以让它包含特定实体。以下是我的存储库中的一些示例代码。

   public TEntity GetById(Guid id)
        {
            return id != Guid.Empty ? GetSet().Find(id) : null;
        }
   private IDbSet<TEntity> GetSet()
            {
                return _unitOfWork.CreateSet<TEntity>();
            }

GetByID 方法调用 GetSet 以返回实体集。我在想,如果我能以某种方式传入一组实体以包含(通过表达式)作为我的 GetById 的一部分,这样我就不必将 GetSet 公开给我的服务。所以,像这样:

var entity = _repository.GetById(theId, e => {e.Prop1, e.Prop2, e.Prop3});

然后我可以将该表达式传递给我的 GetSet 方法并将其传递给一个包含语句。想法?

4

4 回答 4

17

我最近在我的代码中做了类似的事情。以下内容对您有用吗?

public TEntity GetById(Guid id, params Expression<Func<TEntity, object>>[] includeProperties)
    {
        if (id == Guid.Empty) return null;

        var set = _unitOfWork.CreateSet<TEntity>();
        foreach(var includeProperty in includeProperties)
        {
             set.Include(includeProperty);
        }
        return set.First(i => i.Id == id);
    }

然后你会这样称呼它......

var entity = _repository.GetById(theId, e => e.Prop1, e=> e.Prop2, e=> e.Prop3);

我知道这并不完全符合您的模式,但我认为您可以根据需要对其进行重构。

于 2011-08-26T17:33:14.330 回答
8

我认为 Paige Cook 的代码不会像所示的那样工作。

我已经包含了应该可以工作的代码的修改版本:

public TEntity GetById(Guid id, params Expression<Func<TEntity, object>>[] includeProperties)
{
    if (id == Guid.Empty) return null;

    IQueryable<TEntity> set = _unitOfWork.CreateSet<TEntity>();

    foreach(var includeProperty in includeProperties)
    {
         set = set.Include(includeProperty);
    }
    return set.First(i => i.Id == id);
}

我只是通过跟踪 Entity Framework 生成的 SQL 才发现这一点,并意识到原始代码只是通过使用延迟加载来填充指定包含的实体,从而给人一种工作的错觉。

实际上,使用 LINQ Aggregate 方法应用 Include 语句有更简洁的语法,该方法在链接到的博客文章中。我的帖子还通过在不需要包含时回退到 Find 方法来稍微改进该方法,并且还展示了如何使用类似语法实现“GetAll”方法的示例。

于 2012-05-05T16:19:46.577 回答
1

出于多种原因,将上下文存储在非本地空间中是个坏主意。

我修改了史蒂夫的代码并为我的 ASP.NET MVC 项目获取了这个:

public aspnet_User FirstElement(Func<aspnet_User, bool> predicate = null, params Expression<Func<aspnet_User, object>>[] includes)
    {
        aspnet_User result;
        using (var context = new DataContext())
        {
            try
            {
                var set = context.Users.AsQueryable();

                for (int i = 0; i < includes.Count(); i++ )
                    set = set.Include(includes[i]);

                if (predicate != null)
                    result = set.ToList().FirstOrDefault(predicate);
                else
                    result = set.ToList().FirstOrDefault();
            }
            catch
            {
                result = null;
            }
        }

        return result;
    }
于 2015-01-14T11:32:21.880 回答
0

include 方法可以像这样在您的 linq 查询中串在一起:

var result = (from i in dbContext.TableName.Include("RelationProperty")
                                           .Include("RelationProperty")
                                           .Include("RelationProperty")
                select i);
于 2011-08-26T15:43:32.953 回答