Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.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# 如何在EF6中手动构造表达式以匹配相同的输出?_C#_Linq To Sql_Entity Framework 6 - Fatal编程技术网

C# 如何在EF6中手动构造表达式以匹配相同的输出?

C# 如何在EF6中手动构造表达式以匹配相同的输出?,c#,linq-to-sql,entity-framework-6,C#,Linq To Sql,Entity Framework 6,我试图手动构建表达式树。当EF无法将表达式转换为sql或需要构造动态查询时,它可能会有所帮助。不管我怎么看,这都有助于理解引擎盖下发生的事情。 我试图构造简单的“where”查询。在我看来,这与lambda构造的相同。但是,sql输出不同 手动构造表达式: ParameterExpression param = Expression.Parameter(typeof(Transfer)); var manualExpr = Expression.Lambda<Func<Transfe

我试图手动构建表达式树。当EF无法将表达式转换为sql或需要构造动态查询时,它可能会有所帮助。不管我怎么看,这都有助于理解引擎盖下发生的事情。 我试图构造简单的“where”查询。在我看来,这与lambda构造的相同。但是,sql输出不同

手动构造表达式:

ParameterExpression param = Expression.Parameter(typeof(Transfer));
var manualExpr = Expression.Lambda<Func<Transfer, bool>>(
    body: Expression.AndAlso(
        left: Expression.Equal(Expression.Property(param, nameof(Transfer.DestinationFromId)), Expression.Constant(transferDto.DestinationFromId, typeof(Int32))),
        right: Expression.Equal(Expression.Property(param, nameof(Transfer.DestinationToId)), Expression.Constant(transferDto.DestinationToId, typeof(Int32)))
    ), 
    parameters: param
);

var result = await DataContext.Transfers.Where(manualExpr).ToListAsync();
Expression<Func<Transfer, bool>> funcExpr = (t) => t.DestinationFromId == transferDto.DestinationFromId && t.DestinationToId == transferDto.DestinationToId;
var res = await DataContext.Transfers.Where(funcExpr).ToListAsync();
Lambda(函数)构造表达式:

ParameterExpression param = Expression.Parameter(typeof(Transfer));
var manualExpr = Expression.Lambda<Func<Transfer, bool>>(
    body: Expression.AndAlso(
        left: Expression.Equal(Expression.Property(param, nameof(Transfer.DestinationFromId)), Expression.Constant(transferDto.DestinationFromId, typeof(Int32))),
        right: Expression.Equal(Expression.Property(param, nameof(Transfer.DestinationToId)), Expression.Constant(transferDto.DestinationToId, typeof(Int32)))
    ), 
    parameters: param
);

var result = await DataContext.Transfers.Where(manualExpr).ToListAsync();
Expression<Func<Transfer, bool>> funcExpr = (t) => t.DestinationFromId == transferDto.DestinationFromId && t.DestinationToId == transferDto.DestinationToId;
var res = await DataContext.Transfers.Where(funcExpr).ToListAsync();
正如您所观察到的,sql中where语句的输出是不同的。手动表达式使用内联值。lambda使用属性参数为SQLServer缓存查询打开可能性。
我构造的查询是否错误?

要构建相同的表达式,需要稍微更改代码:

var manualExpr = Expression.Lambda<Func<Transfer, bool>>(
    body: Expression.AndAlso(
        left: Expression.Equal(Expression.Property(param, nameof(Transfer.DestinationFromId)),
           // instead of using direct constant value,
           // we build expression transferDto.DestinationFromId
           Expression.PropertyOrField(Expression.Constant(transferDto), nameof(transferDto.DestinationFromId))),
        right: Expression.Equal(Expression.Property(param, nameof(Transfer.DestinationToId)),
           // instead of using direct constant value,
           // we build expression transferDto.DestinationToId
           Expression.PropertyOrField(Expression.Constant(transferDto), nameof(transferDto.DestinationToId)))
    ),
    parameters: param
);
var manualExpr=Expression.Lambda(
正文:Expression.AndAlso(
左:Expression.Equal(Expression.Property(param,nameof(Transfer.DestinationFromId)),
//而不是使用直接常量值,
//我们构建transferDto.DestinationFromId表达式
Expression.PropertyOrField(Expression.Constant(transferDto),nameof(transferDto.DestinationFromId)),
右:Expression.Equal(Expression.Property(param,nameof(Transfer.destinationId)),
//而不是使用直接常量值,
//我们构建表达式transferDto.DestinationId
Expression.PropertyOrField(Expression.Constant(transferDto),nameof(transferDto.destinationId)))
),
参数:param
);
当前表达式与以下表达式相同:

Expression<Func<Transfer, bool>> funcExpr = (t) => t.DestinationFromId == 11 && t.DestinationToId == 13)
Expression funcExpr=(t)=>t.DestinationFromId==11&&t.DestinationToId==13)

这与您所使用的表达式不完全相同。

据我所知,
PropertyOrField
expression是EF表示SQL的查询参数的特定方式?@unsafePtr实际上不是。我使用的是
PropertyOrField
,但在本例中,它可以是
Property
(因此,在其他地方也可以使用)。当您访问外部对象的属性时(
transferDto
,在本例中),EF将使用参数。但是当你使用文字(
DestinationFromId==11
)时,它不会也会使用文字。请你举一个只使用
属性
用法的例子。在上面的代码中,只需将
属性
替换为
属性
,不需要做其他更改。对不起,打扰了我。但是,如果我们在构建表达式树之前需要更改值呢。我尝试检查参数中提供的前一天是否大于或等于。经过一些实验,我通过以下方式实现了这一点:Expression.Property(Expression.Constant(new TransferDto{Time=TransferDto.Time.AddDays(-1)})、nameof(TransferDto.Time))。这都是因为
属性
表达式。在构造函数中,您应该指定属性的名称。我写得对吗,还是有一种优美的方式?