. net Core - EF -试图用数字匹配/替换字符串,导致System.InvalidOperationExce



我必须在SQL中匹配带有最小/最大范围的邮政编码的记录

挑战在于数据质量很差,一些邮政编码不仅仅是数字

所以我试着匹配"好的邮政编码">通过丢弃坏的或者甚至只保留数字

  • 我不知道如何使用Regex.Replace(…)@" [^ d]",")而不是Regex.Match(…, @"d")以适应下面的查询
  • 我得到一个错误的代码在运行时

我试着

  • 正则表达式。IsMatch
  • SqlFunctions。IsNumeric

它们都会在运行时导致错误,下面是代码:

var data = context.Leads.AsQueryable();
data = data.Include(p => p.Company).Include(p => p.Contact);
data = data.Where(p => Regex.IsMatch(p.Company.ZipCode, @"d"));
data = data.Where(p => Convert.ToInt32(p.Company.ZipCode) >= range.Min);
data = data.Where(p => Convert.ToInt32(p.Company.ZipCode) <= range.Max);

错误如下:

System.InvalidOperationException: The LINQ expression 'DbSet<Lead>
.Join(
outer: DbSet<Company>, 
inner: l => EF.Property<Nullable<int>>(l, "CompanyId"), 
outerKeySelector: c => EF.Property<Nullable<int>>(c, "Id"), 
innerKeySelector: (o, i) => new TransparentIdentifier<Lead, Company>(
Outer = o, 
Inner = i
))
.Where(l => !(Regex.IsMatch(
input: l.Inner.ZipCode, 
pattern: "d")))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().

我不知道如何解决这个问题。我真的不明白AsEnumerable()、AsAsyncEnumerable()、ToList()或ToListAsync()在这里有什么帮助

我做错了什么?

谢谢你的帮助

我试了所有能想到的

各种各样的linq/ef技巧,我甚至试图定义一个从未找到的DBFunction

一旦我有了一个直接用SQL编写的正在运行的存储过程,我最终得到了一个列表,而不是一个IQueryable,所以我回到了#1

最后,我在表中创建了一个新字段:

ZipCodeNum

保存邮政编码字符串

的过滤转换版本。

当你使用可查询列表时,EF Core 5总是试图将查询转换为SQL,所以你必须使用SQL Server可以理解的代码。如果你想使用c#函数,你必须先使用ToList()ToArray()下载数据到服务器,然后你可以使用下载的数据使用任何c#函数。

你可以尝试这样做:

var data = context.Leads
.Include(p => p.Company)
.Include(p => p.Contact)
.Where(p => 
p.Company.Zipcode.All(char.IsDigit)
&& (Convert.ToInt32(p.Company.ZipCode) >= range.Min)  //or >=1
&&  ( Convert.ToInt32(p.Company.ZipCode) <= range.Max) ) // or <=99999
.ToArray();

最新更新