将多个 Include 语句传递到存储库中?

发布于 2024-12-01 17:44:39 字数 596 浏览 2 评论 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 暴露给我的服务。所以,像这样:

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

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

I am trying to figure out a way to pass a collection of include statements into my repository so that I can have it include specific entities. Below is some sample code from my repository.

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

The GetByID method calls the GetSet to return the entity set. I was thinking, if I could somehow pass in a collection of entities to include (via an expression) as part of my GetById, this way I wouldn't have to expose the GetSet to my services. So, something like this:

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

I could then pass that expression into my GetSet method and pass it into an include statement. Thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦太阳 2024-12-08 17:44:39

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

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);
    }

然后你可以这样称呼它...

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

我知道这并不完全遵循您的模式,但我认为您可以根据需要重构它。

I have done something like this in my code recently. Would the following work for you?

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);
    }

Then you would call it like this...

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

I know this doesn't exactly follow your pattern, but I think you could refactor it as required.

日久见人心 2024-12-08 17:44:39

我认为 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);
}

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

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

I don't think Paige Cook's code will work quite as shown.

I've included a modified version of the code that should work instead:

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);
}

I only spotted this by tracing the SQL generated by Entity Framework, and realised the original code was only giving the illusion of working, by using lazy-loading to populate the entities specified for inclusion.

There's actually a more terse syntax for applying the Include statements using the LINQ Aggregate method, which is in the blog post linked to. My post also improves the method slightly by having a fall-back to the Find method, when no includes are needed and also shows an example of how to implement a "GetAll" method, using similar syntax.

夏日浅笑〃 2024-12-08 17:44:39

由于多种原因,将上下文存储在非本地空间中并不是一个好主意。

我修改了 Steve 的代码并为我的 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;
    }

It's bad idea to store context in non-local space, for many reasons.

I modify Steve's code and get this for my ASP.NET MVC projects:

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;
    }
雪花飘飘的天空 2024-12-08 17:44:39

include 方法可以在 linq 查询中串联在一起,如下所示:

var result = (from i in dbContext.TableName.Include("RelationProperty")
                                           .Include("RelationProperty")
                                           .Include("RelationProperty")
                select i);

The include method can be strung together in your linq query like so:

var result = (from i in dbContext.TableName.Include("RelationProperty")
                                           .Include("RelationProperty")
                                           .Include("RelationProperty")
                select i);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文