【问题标题】:How to search with LINQ entites having string[] array properties and find these containing any of string from string[] array?如何使用具有字符串 [] 数组属性的 LINQ 实体进行搜索并找到这些包含字符串 [] 数组中的任何字符串的实体?
【发布时间】:2020-05-27 11:58:14
【问题描述】:

在 EF Core 2.2 中,我拥有具有 string[] 数组属性的实体,其中在 ApplicationDbContext 中检索它们:

modelBuilder.Entity<FruitBasket>()
            .Property(e => e.FruitTypes)
            .HasConversion(
                v => string.Join(',', v),
                v => v.Split(',', StringSplitOptions.RemoveEmptyEntries));

例如,一个实体垫在 FruitType 列中包含一个字符串数组:{"Apple", "Banana", "Orange"} 在数据库中保存为:Apple,Banana,Orange

我试图在我的数据库中查找包含输入字符串中任何字符串的所有对象,可以说任何一个:

string[] BasketSearchedFruitTypes = new string[] { "Apple", "Grapefruit", "Pineaple" }

我的 IQueryable:

IQueryable<BasketModel> baskets = GetBasketsQueryable(); //BasketModel contains FruitType string[] prop

搜索我现在拥有的 LINQ 实体:

if (search.BasketSearchedFruitTypes != null && search.BasketSearchedFruitTypes.Length != 0)
baskets = baskets
   .Where(data => search.BasketSearchedFruitTypes
   .Any(x => data.FruitType
   .Contains(x)));

不幸的是,它没有给我任何回报,我也没有想法了。

编辑 1: 使用表达式后:

baskets = baskets
   .Where(data => search.BasketSearchedFruitTypes
   .Any(x => data.FruitType
   .Contains(x)));

当我尝试将其添加到列表中时,我得到了ArgumentNullException。我也不能在上面使用foreach.Count()。和我一样:

var result = baskets.Where(data => search.BasketSearchedFruitTypes.Intersect(data.FruitType).Any();

编辑 2: 我刚刚注意到,foreach 循环通过返回的 IQueryable,但在某些时候会中断给ArgumentNullException。即使循环内部的try catch 也无济于事......

编辑 3: 实际上,当我将返回的 IQueryable 的 foreach 放入 try catch 时,这是一种临时解决方案,并且效果很好。但我仍然不明白为什么它在枚举时崩溃(循环,而不是循环内的代码)。

【问题讨论】:

  • 你可以试试这种方式var result = baskets.Where(data =&gt; search.BasketSearchedFruitTypes.Any(x =&gt; x.Contains(data.FruitType)));
  • @Phong data.DetailedType 给了我一个例外,无法将string[] 转换为char
  • 你可以使用Intersect来实现它var result = baskets.Where(data =&gt; search.BasketSearchedFruitTypes.Intersect(data.FruitType).Any();
  • @Phong 它仍然没有给我任何结果
  • 如果你去掉Where子句,你会得到什么结果?

标签: c# arrays linq iqueryable ef-core-2.2


【解决方案1】:

如果我在您的数据库协议中列出类似的列表,那么这些代码对我有用。

using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp2
{
    class BuilderClass
    {
        List<BasketModel> baskets;

        public BuilderClass()
        {
            baskets = new List<BasketModel>() 
            { new BasketModel { FruitType = new string[] { "Apple", "Grapefruit", "Pineaple", "Bing Cherry", "Cantaloupe" } },
              new BasketModel { FruitType = new string[] { "Grapefruit", "Cantaloupe", "Pineaple", "Boysenberries", "Apple" } },
              new BasketModel { FruitType = new string[] { "Clementine", "Bing Cherry", "Boysenberries", "Cantaloupe", "Entawak" } },
              new BasketModel { FruitType = new string[] { "Entawak", "Grapefruit", "Apple", "Pineaple", "Cantaloupe" } },
              new BasketModel { FruitType = new string[] { "Apple", "Pineaple", "Bing Cherry", "Entawak", "Grapefruit" } }
            };
        }

        string[] BasketSearchedFruitTypes = new string[]
        { "Apple", "Grapefruit", "Pineaple" };

        public void check()
        {
            var qbaskets = baskets.AsQueryable();
            if (BasketSearchedFruitTypes != null && BasketSearchedFruitTypes.Length != 0)
            {
                var result = qbaskets.Where(data => BasketSearchedFruitTypes.Any(x => data.FruitType.Contains(x))).ToList();
                // result have list with count of 4
            }
        }
    }

    class BasketModel
    {
        public string[] FruitType { get; set; }
    }
}

【讨论】:

  • 您的解决方案运行良好。经过调查,我意识到我的可为空值导致了问题。但我将您的回复标记为对我的问题的正确解决方案。
猜你喜欢
  • 2010-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 2023-03-24
相关资源
最近更新 更多