Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.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
Entity framework 实体框架-荒谬的查询,将smallint转换为int进行比较_Entity Framework_Entity Framework 6 - Fatal编程技术网

Entity framework 实体框架-荒谬的查询,将smallint转换为int进行比较

Entity framework 实体框架-荒谬的查询,将smallint转换为int进行比较,entity-framework,entity-framework-6,Entity Framework,Entity Framework 6,这里没有想法。我有一个简单的表,模型首先映射到实体框架,生成了以下SQL: (@p__linq__0 int,@p__linq__1 int)SELECT [Extent1].[BucketRef] AS [BucketRef], [Extent1].[VariantNo] AS [VariantNo], [Extent1].[SliceNo] AS [SliceNo], [Extent1].[TradeNo] AS [TradeNo], [Ex

这里没有想法。我有一个简单的表,模型首先映射到实体框架,生成了以下SQL:

(@p__linq__0 int,@p__linq__1 int)SELECT 
    [Extent1].[BucketRef] AS [BucketRef], 
    [Extent1].[VariantNo] AS [VariantNo], 
    [Extent1].[SliceNo] AS [SliceNo], 
    [Extent1].[TradeNo] AS [TradeNo], 
    [Extent1].[TradeBegin] AS [TradeBegin], 
    [Extent1].[TradeEnd] AS [TradeEnd], 
    FROM [simstg].[Trade] AS [Extent1]
    WHERE ((( CAST( [Extent1].[BucketRef] AS int) = @p__linq__0) AND ( NOT (( CAST( [Extent1].[BucketRef] AS int) IS NULL) OR (@p__linq__0 IS NULL)))) OR (( CAST( [Extent1].[BucketRef] AS int) IS NULL) AND (@p__linq__0 IS NULL))) AND ((( CAST( [Extent1].[VariantNo] AS int) = @p__linq__1) AND ( NOT (( CAST( [Extent1].[VariantNo] AS int) IS NULL) OR (@p__linq__1 IS NULL)))) OR (( CAST( [Extent1].[VariantNo] AS int) IS NULL) AND (@p__linq__1 IS NULL)))
所有这些演员都会扼杀表演。遗憾的是,我看不出它们来自哪里

问题是:

var tradesQuery = repository.SimStgTrade
    .Where(x => x.BucketRef == bucketId && x.VariantNo == set)
    .ToArray();
这很容易。字段定义为:bucketId:short(数据库中的smallint)、set short、数据库中的smallint。因此,完全不需要演员阵容。我已经删除并重新创建了模型中的表——据我所知,映射匹配(字段为smallint)。因此,我们在性能方面遇到了严重问题,如:查询超时,因为它不使用表扫描

有人知道如何摆脱这些演员阵容,并迫使他们以短裤为基础进行比较吗?从SQL中可以明显看出,EF决定首先将所有内容移动到int。。。。这毫无意义


这不是一件“很好”的事情。未完成的查询路径完全不同,生成的代码将其转换为自连接。在服务器管理器中,EF变量需要5分钟以上的时间,而使用简单SQL的优化版本需要0.0秒(返回该表中大约十亿行中的228行)。

您需要使用类中的静态函数自己创建
Where
表达式

像这样:

Int16 bucketId = 3;

var parameter = Expression.Parameter(typeof(SimStgTrade));
var property = Expression.PropertyOrField(parameter, "BucketRef");
var constant = Expression.Constant(bucketId);
var comparison = Expression.Equal(property, constant);

var lambda = Expression.Lambda<Func<SimStgTrade,bool>>(comparison, parameter);

var tradesQuery = repository.SimStgTrade
  .Where(lambda)
  .Where(x => x.VariantNo == set)
  .ToArray();
Int16 bucketId=3;
var参数=Expression.parameter(typeof(simstgtgrade));
var property=Expression.PropertyOrField(参数“BucketRef”);
var常量=表达式常量(bucketId);
var比较=表达式.Equal(属性,常量);
var lambda=表达式.lambda(比较,参数);
var tradeskry=repository.SimStgTrade
.何处(lambda)
.其中(x=>x.VariantNo==set)
.ToArray();

VariantNo==set
执行同样的操作,以便删除该强制转换

对于不同的LINQ提供程序,这种行为可能很常见,而不仅仅是EF特定的,因为C#编译器是如何为Where表达式生成表达式树的

当您将条件指定为:

.Where(x => x.BucketRef == bucketId)
BucketRef和bucketId都是short,编译器为比较的两个部分生成从short到int的转换,因为没有为short类型定义==运算符。答案是这样的

作为一种解决方法,您可以通过以下方式重写条件:

.Where(x => x.BucketRef.Equals(bucketId))

这有效地消除了比较中的cast。

实际上有一个更简单的解决方法。var bucketsfilter=new[]{bucketId};then.Where(x=>bucketsfilter.Contains(x.BucketRef)-也没有大小写。在上找到它,smallint.Zero Quality控件也是如此-非常明显。这对于进行除Equal之外的其他比较非常有帮助。只需替换Expression.Equal by Expression.GreaterThan或Expression.Less即可。例如,我的SQL查询不再包含不需要的“强制转换”操作。投票关闭我自己-这类似于上的问题-仅针对smallint。我不会删除它,因为我认为它应该作为参考。这是一个简单的解决方法,效果足够好。您是否尝试过将模型更改为使用Int而不是Short,以查看它是否删除强制转换。在这种情况下,您对较小的内存占用会在数据库访问中丢失。不,我没有。该模型有一个short,因为它是一个short。该表目前有100亿个条目,而这2个字节更多将导致更多的数据。我们正是出于这个原因优化了空间使用。这是一个每天输入5亿行的表。我们没有问题在键为int的其他表上-这是smallint/tinyint特有的。当该表为数百gb时,数据库空间相当大。对于228行,差异为5分钟15秒,小于1秒。根据我的链接,解决方法已确认,现在正在生产中。