【问题标题】:Sqlite EF Core 5 won't let me do case insensitive searchesSqlite EF Core 5 不允许我进行不区分大小写的搜索
【发布时间】:2021-04-01 23:45:39
【问题描述】:

所以我尝试使用 ef-core 进行 linq 查询以进行 where 搜索,但无论我尝试了什么,我都无法让它进行不区分大小写的搜索。

如果我搜索“星期二”,它不会获取任何数据,因为数据库中的所有内容都保存为“星期二”。

经过搜索,我发现您必须通过 ef 核心迁移告诉 sqlite,您希望它对每个属性的以下代码不区分大小写。

b.Property<string>("DayOfWeek")
    .HasColumnType("TEXT COLLATE NOCASE");

该信息在 ContextModelSnapshot.cs 文件中。

所以我这样做了,删除了数据库并执行了“更新数据库”,创建了一个新数据库但没有任何改变。

现在我当然可以在每次搜索中使用 .ToLower(),但如果我忘记将其添加到每个 where 子句中,这只会影响性能并增加失败的可能性。

我正在使用以下软件包来创建、迁移和访问数据库。

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.1">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.1">

我遗漏了什么,或者我是否误解了 sqlite 不区分大小写查询的整个概念?

【问题讨论】:

  • 嗨@Johan Knape,关于此案的任何更新?
  • 嗨@Yinqiu,它仍然不起作用。可能是我使用的是 sqlite 而不是 sqlserver,并且该命令不适用于 sqlite 数据库。
  • 嗨@Johan Knape,你可以看到这个link

标签: sqlite asp.net-core entity-framework-core


【解决方案1】:

您可以使用以下代码将属性配置为不区分大小写。

在您的上下文中:

 protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.UseCollation("BINARY");

        modelBuilder.Entity<Entry>().Property(c => c.DayOfWeek)
            .UseCollation("NOCASE");
    }

使用此设置,DayOfWeek 将不区分大小写,而其他列仍将被区分。

【讨论】:

  • 如果我只是说我需要所有文本字段不区分大小写,我猜你应该能够给我这个答案。那么下次我会提出一个更好的问题,你生活和学习:-)
  • 是的,我误以为你只需要该列不区分大小写,哈哈。
【解决方案2】:

不幸的是,提供的答案对我不起作用。以下是如何将所有公开模型的所有 string 属性迭代到 EF-Core 并将其默认排序规则设置为 nocase

public static void SetCaseInsensitiveSearchesForSQLite(this ModelBuilder modelBuilder)
{
    if (modelBuilder == null)
    {
        throw new ArgumentNullException(nameof(modelBuilder));
    }

    modelBuilder.UseCollation("NOCASE");

    foreach (var property in modelBuilder.Model.GetEntityTypes()
                                            .SelectMany(t => t.GetProperties())
                                            .Where(p => p.ClrType == typeof(string)))
    {
        property.SetCollation("NOCASE");
    }
}

然后这样称呼它:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    if (modelBuilder == null)
    {
        throw new ArgumentNullException(nameof(modelBuilder));
    }

    modelBuilder.SetCaseInsensitiveSearchesForSQLite();
}

【讨论】:

    【解决方案3】:

    所以经过大量测试,我终于找到了我的错误。

    事实证明,您只需将 OnModelCreating 中的排序规则更改为 NOCASE,它就会突然变得无处不在。

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
      modelBuilder.UseCollation("NOCASE");
    }
    

    【讨论】:

    • 嗨@Johan Knape,如果我像下面这样配置它会有效吗?
    • @Yinqiu 不确定,它看起来比它需要的更复杂。如果我这样做,我必须确保我的 OnModelCreating 具有我的数据库中的每个文本列,这将是相当多的。如果我只对迁移文件执行此操作,则只需在此处执行那些文本列。我认为这将使其更易于维护。
    猜你喜欢
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    • 2013-02-24
    • 2013-04-17
    • 2012-12-20
    相关资源
    最近更新 更多