【问题标题】:Search a comma separated value using Entity framework使用实体框架搜索逗号分隔值
【发布时间】:2020-03-19 09:43:35
【问题描述】:

我有以下字符串 3,9 我想在一个看起来像 follow 的数据库表中搜索它的 2 个值(3 和 9)

所以如果我的字符串只包含数字 3,我的查询应该返回所有 5 行,如果我发送数字 9,它应该只返回 2 行,如果我发送 3,9,它也应该返回所有 5 行

我在课堂上编写代码时遇到问题

var t = GetAll()
 if (!string.IsNullOrEmpty(ApproversId))
        {
            List<string> ApproversIdL = ApproversId.Split(',').ToList();
            // this is where i am having trouble
            t = t.Where(s => s.AproversIds.Any(x=>x.ToString()== ApproversIdL.Any(x=>x.ToString())));                                
        }

感谢任何帮助

【问题讨论】:

  • 是EntityFramework还是EntityFrameworkCore?
  • 实体框架Core
  • EF 是一个 ORM,所以真正的答案是使用关系模式,在这种情况下是多对多映射。 IE。如果这是一个 Submissions 表,其中一个提交可以有多个批准者,并且一个批准者链接到许多提交,具有一个 SubmissionApprovers 表。从此,您可以在数据库级别执行这些过滤器检查,而不是先将所有数据加载到内存中。

标签: c# asp.net asp.net-mvc entity-framework asp.net-core


【解决方案1】:

我想t = GetAll() 是一个有行的列表。

因此,您必须以与拆分 ApproversId 参数相同的方式拆分每个 t.AproversIds 列值并检查是否有任何交集

var ApproversIdL = ApproversId.Split(',');
t = t.Where(s => s.AproversIds.Split(',').Any(p => ApproversIdL.Contains(p) ));

【讨论】:

  • 我试过了,但是这个 's.AproversIds.Split(',')' 给出错误提示:表达式树可能不包含使用可选参数的调用或调用
  • 回复中似乎有错字。试试看:var approversIdL = approversId.Split(","); var matchingList = t.Where(x =&gt; x.Split(",").Any(p =&gt; approversIdL.Contains(p)));
  • 不,是同一个问题
  • @lzydrmr 这是因为GetAll() 返回IQueryable&lt;&gt;,正如我现在所理解的那样,并且未启用局部变量。 @Sora恐怕您可以尝试通过带有输入参数的存储过程来解决它。或者它应该使用plain T-SQL approach 解决,没有c# 变量引用
  • @oleksa 感谢您的澄清。或者,您可以将IQueryable&lt;&gt; 转换为List&lt;&gt;(通过调用ToList())。但是,在生产环境中,这对于性能而言可能并不明智。
【解决方案2】:

我在讨论如何搜索多个值并想出了这个问题。 :P

Dictionary<int, string> data = new Dictionary<int, string>();
data.Add(1, "3,97");
data.Add(2, "9,3");
data.Add(3, "3");
data.Add(4, "3");
data.Add(5, "3,4");

//search string with comma separated value
string searchItems = "9";
var tempSearchItems = searchItems;

searchItems = searchItems.Replace(",", "|").Replace(" ", "");

//Pattern for the regex
string pattern = @"\b(" + searchItems + @")\b";

//get the result
var test = data.Where(d => Regex.Matches(d.Value, pattern).Count > 0).ToList();

如果有帮助请告诉我

【讨论】:

  • 这可能适用于这个特殊的示例,但如果搜索项包含由正则表达式引擎解释的字符(例如星号),则会导致问题。
  • 问题是关于EntityFramework的问题,GetAll返回IQueryable&lt;&gt;(不是IEnumerable&lt;&gt;)。然后附加Where 并转换为SQL。在您开始枚举GetAll() 结果之前,程序内存中实际上没有数据
  • 这是一个有趣的场景。拆分实际上不会调用内存中的数据吗?这是否意味着在 split 执行时查询已经执行?此外,如果数据包含两位数且搜索字符串包含一位数,则 Contains 将给出错误匹配。
【解决方案3】:

如果您使用 SQL Server,则可以使用 SqlMethods.Like 将数据库结果集过滤为可管理的数据子集,然后可以使用 RegEx 提取内存中的项目。

【讨论】:

    【解决方案4】:

    这是一个你可以参考的工作演示

     public async Task<IActionResult>  Test()
        {
            var ApproversId = "3,9";
            var t = (from a in _context.Answers
                    select a).ToList();
            if (!string.IsNullOrEmpty(ApproversId))
            {
                List<string> ApproversIdL = ApproversId.Split(',').ToList();
                t = t.Where(s => ApproversIdL.Any(al=>s.AproversIds.Contains(al))).ToList();
    
            }
            return View();
        }
    

    结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-08
      • 2019-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多