Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF Core LINQ,其中带有扩展方法的未转换为SQL_C#_Linq_.net Core_Entity Framework Core_Linq To Entities - Fatal编程技术网

C# EF Core LINQ,其中带有扩展方法的未转换为SQL

C# EF Core LINQ,其中带有扩展方法的未转换为SQL,c#,linq,.net-core,entity-framework-core,linq-to-entities,C#,Linq,.net Core,Entity Framework Core,Linq To Entities,给出以下查询: context.ToolingOrders .Include(r => r.ToolingOrderDetails) .Include(r => r.PurchaseOrder) .Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && r.PoNumber.ContainsOrEmpty(filter.PoNumber)) 我使用这些扩展方法来保存一些代码: co

给出以下查询:

context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && 
            r.PoNumber.ContainsOrEmpty(filter.PoNumber))
我使用这些扩展方法来保存一些代码:

context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && 
            r.PoNumber.ContainsOrEmpty(filter.PoNumber))
 public static class FilterExtensions
 {
        public static bool ContainsOrEmpty(this string source, string toCheck)
        {
            return string.IsNullOrWhiteSpace(toCheck) || source?.IndexOf(toCheck, StringComparison.OrdinalIgnoreCase) >= 0;
        }

        public static bool EqualsOrNull(this int source, int? toCheck)
        {
            return !toCheck.HasValue || source == toCheck;
        }
 }
问题是,由于这些扩展方法,Where部分没有转换为SQL

context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && 
            r.PoNumber.ContainsOrEmpty(filter.PoNumber))
我使用.NETCore2.2,它有这样的功能,这完全隐藏了这个问题,但SQL分析器还是显示了它

context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && 
            r.PoNumber.ContainsOrEmpty(filter.PoNumber))

有什么方法可以让它工作,或者我必须明确地编写where部分的每一部分吗?

您可以为您的特定对象扩展
IQueryable

context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && 
            r.PoNumber.ContainsOrEmpty(filter.PoNumber))
以以下对象为例:

context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && 
            r.PoNumber.ContainsOrEmpty(filter.PoNumber))
公共类MyObject
{
公共财产;
}
您可以编写如下扩展:

context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && 
            r.PoNumber.ContainsOrEmpty(filter.PoNumber))
公共静态类MyQueryExtension
{
公共静态IQueryable where MyPropertyNull(此IQueryable可查询)
{
返回queryable.Where(obj=>obj.MyProperty==null);
}
}
然后像这样使用它:

context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && 
            r.PoNumber.ContainsOrEmpty(filter.PoNumber))
var queryable=new List().AsQueryable();
var result=queryable.WhereMyPropertyNull().ToList();
编辑

context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && 
            r.PoNumber.ContainsOrEmpty(filter.PoNumber))
根据一些反馈,我更新了我的答案来处理泛型

context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && 
            r.PoNumber.ContainsOrEmpty(filter.PoNumber))
公共静态类扩展
{
公共静态IQueryable equalFull(此IQueryable源、Func选择器、TProperty匹配)
{
返回source.Where(entity=>Match(selector.Invoke(entity),Match));
}
私有静态布尔匹配(tenty实体、TProperty匹配)
{
if(实体==null){
返回true;
}否则{
返回实体。等于(匹配);
}
}
}
它可用于将属性值传递给where语句:

context.ToolingOrders
.Include(r => r.ToolingOrderDetails)
.Include(r => r.PurchaseOrder)
.Where(r => r.VendorId.EqualsOrNull(filter.VendorId) && 
            r.PoNumber.ContainsOrEmpty(filter.PoNumber))
var list=newlist();
添加(新的MyObject{MyProperty=“Test”});
添加(新的MyObject{MyProperty=“NoMatch”});
添加(新的MyObject{MyProperty=null});
var result=list.AsQueryable()
.EqualOrNull(o=>o.MyProperty,“测试”)
.ToList();

@Train您确定这就是您要发布的链接吗?仅供参考,当使用转换为SQL的LInq时,字符串比较的大小写敏感度将由DB的排序规则决定(通常不区分大小写)@juharr很好,但如果筛选器值为空,我们仍然必须处理该情况,然后不要过滤它。很抱歉,由于某种原因,它是错误的链接。您的问题是,您混合了客户端表达式,而这些表达式不能转换为sql查询。我知道这将是一条更长的路,但我建议要么完全重建查询,以便将其转换为SQL,要么将其拉入内存,然后使用这些操作进行过滤。如果这种情况继续下去,你将来的日子会更难过。我在30个不同的查询中对完全不同的实体使用这些方法,因此我认为这没有多大帮助。通过传递
表达式来选择要比较为null的列,这可以变得通用。我认为这不仅使事情变得简单,而且使事情变得复杂。只要再检查一下我的问题,你就会发现,你的解决方案并不能解决我的问题。考虑下面的内容:我们有一个带有电子邮件字段的用户实体,我们也想在一个不同的地方过滤它,你会如何用一个通用表达式来做呢?用户和工具顺序中没有什么共同点……我刚刚尝试了这种方法,它看起来是个好主意,但EF仍然没有将其转换为SQL,在客户端执行Where部分。这是已分析的SQL查询,没有where子句:从[ToolingOrder]中选择[r].[Id],[r].[BillTo],[r].[CreateDate]作为[r]左连接[PurchaseOrders]作为[r].[PurchaseOrderId]=[r.PurchaseOrder]。[Id]订单由[r].[CreateDate]描述[r].[Id]