【问题标题】:Combining Linq-Entity statements结合 Linq-Entity 语句
【发布时间】:2018-05-14 19:10:51
【问题描述】:

我有 2 个存储库,成员和人员。人员模型包含一个成员模型的可为空的引用属性。成员模型是在成员存储库中定义的,我想制定一个模式来确保保持这种状态。但是,当我从人员仓库调用成员仓库中的方法时,我得到了

LINQ to Entities 无法识别方法 'System.Linq.IQueryable 1[...IMember] Get(..Entities,System.Linq.Expressions.Expression 1[System.Func`2[..tblMember,System .Boolean]])' 方法,并且该方法不能翻译成 store 表达式。"

虽然我知道这可以通过放置 .asEnumerable() 然后第二次选择来轻松解决,这意味着您执行 2 个查询而不是一个查询,并且您失去了将方法公开为等待的能力。下面是我删除了一些非必要部分以清除的代码。我没有使用 lambda,因为我还没有找到一个好方法来表示 let in lambda 表达式。我的目标是 person.Member 只是一个嵌套选择。另请注意,Member 方面是一个非常丑陋的数据库,我无法控制,这些 repos 被分开是有原因的。提前致谢

 public class MemberRepository : Interfaces.IRepository<IMemberBase, string>
{
    private Data.LSAEntities entities { get; set; }

    public MemberRepository(Data.LSAEntities entities)
    {
        this.entities = entities;
    }


    internal static IQueryable<IMember> Get(Data.LSAEntities entities, Expression<Func<tblMember, bool>> predicate)
    {
        return (from t in entities.tblMembers.Where(predicate)
                    let options = entities.tblDataOptions.Where(o => o.DataName == "MemberStatus")
                    select new Member()
                    {
                        MemberID = t.MemberID,
                        ...
                    });
    }
}



public class PersonRepository : IRepository<IPerson, int>
{
    private Data.LSAEntities entities { get; set; }

    public PersonRepository(Data.LSAEntities entities)
    {
        this.entities = entities;
    }

    public IQueryable<IPerson> Get(int key)
    {
        return (from p in entities.tblPersons
                where p.PersonId == key
                select new Person()
                {
                    PersonId = p.PersonId,
                    ...
                    Member = MemberRepository.Get(entities, m=> p.MemberId == m.MemberID).FirstOrDefault()
                });
    }
}

【问题讨论】:

  • 请提供minimal reproducible example 而不仅仅是代码转储
  • 我不清楚你在架构上的意图是什么。如果它们实际上是独立的数据库,那么您将无法运行一个查询来获取相关数据。您得到的错误本质上是由于 LINQ to Entities 希望在数据库中运行整个查询,而您的存储库方法是未知的。我认为您正在尝试通过执行边界限制并且只在服务器上执行一个查询来获得蛋糕并吃掉它。
  • 你完全正确!我的目标是在使用类的开发人员上强制执行存储库模式(数据类型映射),而不必每次我想访问数据时都重写 select 语句。如果我的存储库没有交互,这不会是一个问题,但是,在这种情况下,一个人与一个成员相关,我不想每次我想要参考时都写 select(……..)。此外,通过鼓励将查询编译为单个查询,它允许我使用堆栈中更高的 async/await 模式。
  • @johnny5 用最少的代码更新

标签: c# linq entity-framework-6


【解决方案1】:

这可能会对您有所帮助:

给定

var ans = from a in table
          let b = a.TotalPrice / a.Quantity
          where b > 500
          select new {
              PriceEa = b,
              a.ID,
              a.Description
          };

翻译成

var ans = table.Select(a => new { b = a.TotalPrice / a.Quantity, a })
               .Where(ba => ba.b > 500)
               .Select(ba => new {
                   PriceEa = ba.b,
                   ba.a.ID,
                   ba.a.Description
                });

LINQ 中查询理解语法中的 let 子句转换为 Select,在使用 lambda 语法时添加一个新字段来保存 let 值。

【讨论】:

  • 这很好,我开始使用它而不是 let 但是,您对如何使以下代码工作有任何想法吗? Member = MemberRepository.Get(entities, m=> p.MemberId == m.MemberID).FirstOrDefault()
  • @ChristopherSteven 研究使用 LINQKit。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多