使用 IEnumerable 中的属性值从 DbSet<TEntity> 获取所有实体

这看起来真的很简单,但我似乎无法解决它。使用 EF Core,DbSet<Rule> Rules我的DbContext.


public class Rule

{

    public int Id { get; set; }

    public string Raw { get; set; }

}

我正在尝试编写一个查询,其中,给定一个IEnumerable<string> lines,Rule从DbSet它的Raw值是其中一个元素的位置lines(完全匹配,而不是值的子字符串)中给我所有的s 。


有一段时间,我使用了类似的东西:


private IQueryable<Rule> GetExistingRules() =>

    dbContext.Rules.Where(r => lines.Contains(r.Raw));

但是,此后我发现(我认为)这并没有达到我的预期。(此方法紧随其后的Rule是为lines当前不存在的所有元素插入 new s 。我得到了Rule具有相同Raw值的重复s ...)我认为,相反,我需要使用.Intersect()?


我尝试根据this使用自定义 EqualityComparer ,但它引发了异常。


    private IQueryable<Rule> GetExistingRules()

    {

        var lineRules = lines.Select(l => new Rule {Raw = l});

        return dbContext.Rules.Intersect(lineRules, new RuleRawEqualityComparer());

    }


    private class RuleRawEqualityComparer : IEqualityComparer<Rule>

    {

        public bool Equals(Rule x, Rule y) => x?.Raw == y?.Raw;

        ...

    }

无法解析表达式 'value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[FilterLists.Data.Entities.Rule]).Intersect(__p_0, __p_1)':方法 'System.Linq.Queryable.Intersect 的重载' 目前不支持。


编写此查询的最佳方法是什么?请注意,它处于DbContext交互链中,因此我更愿意将返回类型保留为 anIQueryable以启用 EF 的延迟查询组合。


慕斯王
浏览 195回答 2
2回答

拉风的咖菲猫

不要忘记,当您将 linQ 与 EFCore 和 IQueryable 一起使用时,它会转换 Sql 语句中的 c# 代码。你试过这个吗?var query = from rule in dbContext.Rules&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; join line in lines&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; on rule.Raw equals line&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; select rule;

慕侠2389804

你写了:给我来自 DbSet 的所有规则,其中它的原始值是行中的一个元素(完全匹配等)您的第一个解决方案将提供所需的结果:var requestedRules = dbContext.Rules&nbsp; &nbsp;.Where(rule => lines.Contains(rule));在的话:从收集Rules,只选择那些Rules具有A Raw,等于序列中的值的一个值lines。我得到了具有相同原始值的重复规则......)显然,您的源集合具有具有相同原始值的规则!如果您只想要唯一的原始值,则必须决定如何处理重复项:Id&nbsp; Raw&nbsp;1&nbsp; "Hello"&nbsp;2&nbsp; "Hello"你想要哪一个?首先?最后?两个都?没有任何?任何?让我们选择 Any:我们将创建具有相同 Raw 值的规则组,并且从每个组中我们取第一个(或者如果你想要最后一个,毕竟我们不在乎。但这有点效率低下。var result = dbContext.Rules&nbsp; &nbsp;.Where(rule => lines.Contains(rule))&nbsp; &nbsp;.GroupBy(rule => rule.Raw)&nbsp; &nbsp;.Select(group => group.FirstOrDefault());在的话:从收集Rules,只选择那些Rules具有A Raw,等于序列中的值的一个值lines。从剩余的元素中制作具有相同原始值的规则组。然后从每个 Group 中取出任何元素,例如第一个。如果您想要所有/仅第一个/仅最后一个,您现在就知道该怎么做。
打开App,查看更多内容
随时随地看视频慕课网APP