如何使用实体框架在文本字段中搜索空字符串?

Posted

技术标签:

【中文标题】如何使用实体框架在文本字段中搜索空字符串?【英文标题】:How to search for empty strings in a text field with Entity Framework? 【发布时间】:2016-03-29 16:52:07 【问题描述】:

我想知道当我在实体框架中使用文本类型字段时如何搜索空字符串。

我查看了 Entity 正在生成的 SQL 查询,它使用 LIKE 进行比较,因为它在文本类型字段中搜索,所以当我使用 .Equals(""), == "", == string.Empty , .Contains(""), .Contains(string.Empty) 和其他所有内容,它返回所有结果,因为它的 sql 查询类似于 '' 并且 == 命令抛出异常,因为它使用了无效的 = 命令文本类型字段。

当我尝试使用 .Equals(null), .Contains(null), == null 时,它什么也不返回,因为它正在生成 FIELD ISNULL 命令。

我已经尝试过 .Lenght == 0 但它会引发异常...

【问题讨论】:

where(f => f.MyField == "") 应该可以工作。也许你可以使用 linq Count() 函数:where(f => f.MyField.Count() == 0) 这不可能。 Contains 确实映射到 LIKE,但 == "" 应该生成类似 N'' = [Extent1].[Field] 的东西 请展示一个示例,== string.Empty 和生成的 SQL。你(或我们)一定忽略了一些东西。 亚历山大,Count() == 0 thow 例外:DbExpressionBinding requires an input expression with a collection ResultType.\r\nNome do parâmetro: input,。我想这是因为它是一个字符串而不是一个集合,我必须使用 Lenght。 == "": The data types varchar and text are incompatible in the equal to operator. 对不起,我忘了说 == 在 SQL Query 中映射到 = 并且它会抛出文本类型的异常。我试图强调我已经尝试了所有方法,并且 == string.Empty 表示 equals(string.Empty)。 嗯,这是一个重要的细节。该列具有已弃用的数据类型text,无法搜索。可以改成nvarchar(max)吗? 【参考方案1】:

这对我有用:

public class POCO

    public int Id  get; set; 
    public string Name  get; set; 
    public string Description  get; set; 


static void Main(string[] args)

      var pocos = new List<POCO>
      
          new POCO  Id = 1, Name = "John", Description = "basic" ,
          new POCO  Id = 2, Name = "Jane", Description = "" ,
          new POCO  Id = 3, Name = "Joey", Description = string.Empty 
      ;

  pocos.Where(x => x.Description == string.Empty)
    .ToList()
    .ForEach(x => Console.WriteLine($"x.Id x.Name x.Description"));

但是,如果您使用的是实体框架,则问题可能是您的 T4 生成的对象没有完全实现您可以使用的数据。 EG 来自数据库的翻译没有填充对象以正确询问。我会做这样的操作来看看:

  using (var context = new YOURCONTEXTNAME())
  
    var persons = context.YOURDATABASEOBJECT.ToList();

    persons.ForEach(x => Console.WriteLine($"x.COLUMNINQUESTION"));
  

如果您成功地在其中包含数据,则应该检索它。如果可能,我不会使用文本。使用 varchar(max) nvarchar(max) xml,无论文本最终将被弃用,并且是不好的形式,可以说在这一点上继续使用。

编辑 好的,我明白了,答案是你不能询问对象,直到它是文本时完全实现。我在本地数据库上进行了测试并创建了一个上下文并对其进行了测试,果然你不能在文本上执行 '== string.empty'、'== ""' 或 'String.IsNullOrEmpty()'。但是,一旦对象在已实现的对象中具体化,您就可以执行此操作。例如:

// Won't work as context does not understand type
//var persons = context.tePersons.Where(x => x.Description == string.Empty).ToList();

//Works fine as transformation got the object translated to a string in .NET
var start = context.tePersons.ToList();
var persons = start.Where(x => x.Description == String.Empty).ToList();

这显然会带来一个问题,因为您可能需要在执行谓词之前获取所有数据。无论如何都不是最好的方法。您可以为此创建一个 sql 对象,然后执行一个函数、过程或视图来更改它。

【讨论】:

OP 的comment, now 2 hours ago, 明确表示这是行不通的。我已经建议 OP 迁移到 nvarchar(max)。此外,将包含文本(大对象)的表中的所有数据提取到内存中也是一个坏主意。 我同意这就是我发布此内容的原因:'这显然会带来问题,因为您可能需要在执行谓词之前获取所有数据。无论如何都不是最好的方法。你可以为此做一个 sql 对象,然后做一个函数、过程或视图来改变它。我只是想看看它是否可以完成。 您的编辑和我的评论交叉。无论如何,文本列是不可搜索的,不是通过查询,也不是通过 sproc。 OP 应该通过将其他标准应用于其他列来仔细获取数据。或更改为 (n)varchar。 我同意,但是您可以在将对象实例化为 .NET 生成的 T4 POCO 对象后进行询问。至少当我在本地系统上执行 SQL Server 2014 实例、EF 6.1.3 和 .NET 4.5.2 时。不过,这不是我同意的首选解决方案。 当然你可以搜索string。也许我误解了你的“sql 对象”。

以上是关于如何使用实体框架在文本字段中搜索空字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何在搜索/过滤数据期间处理空字段?

如何在 coredata 中创建数据库视图

截串存取分割文本字符串的方法

如何使用 T-SQL 在数据库中的所有文本字段中搜索某些子字符串

使用实体框架代码优先创建文本列[重复]

使用 LINQ-to-Entities 搜索时忽略空字符串