gpt4 book ai didi

entity-framework - 重用包含 SqlFunctions.DatePart 的表达式

转载 作者:行者123 更新时间:2023-12-03 23:38:26 25 4
gpt4 key购买 nike

我有以下 LINQ-to-Entities 查询,用于检索与给定日期 (dte) 的日期部分匹配的记录:

Dim qry = entities.Works.Where(Function(w) w.JobID = RecordID And
SqlFunctions.DatePart("y", w.FromDate) = SqlFunctions.DatePart("y", dte) And
SqlFunctions.DatePart("m", w.FromDate) = SqlFunctions.DatePart("m", dte) And
SqlFunctions.DatePart("d", w.FromDate) = SqlFunctions.DatePart("d", dte))

我想重用这个表达式,首先要写这样的东西:

Public SqlDateEquals As System.Linq.Expressions
.Expression(Of Func(Of DateTime, DateTime, Boolean)) = Function(dte1, dte2)
SqlFunctions.DatePart("y", dte1) = SqlFunctions.DatePart("y", dte2) And
SqlFunctions.DatePart("m", dte1) = SqlFunctions.DatePart("m", dte2) And
SqlFunctions.DatePart("d", dte1) = SqlFunctions.DatePart("d", dte2)

然后,在其他查询中:

Dim qry = entities.Works.Where(Function(w) w.JobID = 
RecordID And SqlDateEquals(w.FromDate, dte))

我的理解是 LINQ-to-Entities 解析传入 .Where 的表达式,它应该能够将 SqlFunctions.DatePart 识别为表达式的一部分以及。因此,包含 SqlFunctions.DatePart 的表达式仍然可以解析为其等效的 SQL。

我该怎么做?

最佳答案

您看到的问题与SqlFunctions.DatePart 无关;相反,这是因为您无法按照您尝试的方式组合两个表达式。

像这样

编写表达式实际上并不像您想象的那么简单。 lambda 表达式语法是一种简写形式,不支持组合表达式;您必须改用 Expression 上的静态方法。

幸运的是,有一种更简单的方法适合您的情况:

更新:使用 Expression 的静态“构建器”方法,添加了用于长期执行此操作的示例代码。

Imports System.ComponentModel.DataAnnotations
Imports System.Data.Entity
Imports System.Linq.Expressions
Imports System.Data.Objects.SqlClient
Imports System.Reflection

Class Entity
<Key> Public Property Key As Integer
Public Property P As String
End Class

Class Context
Inherits DbContext

Public Property Entities As DbSet(Of Entity)

End Class

Module Module1
Sub Main()
Dim expression1 As Expression(Of Func(Of Entity, Boolean)) = Function(e) e.P > "m"

Dim ctx As Context = New Context()
Dim query = From e In ctx.Entities
Where e.P < "p"
Select e

' Example 1. The easy way: chaining two Where clauses together.
' This works because q.Where(A AND B) is the same as q.Where(A).Where(B)
Dim q2 = query.Where(expression1)

Console.WriteLine(q2.ToString())

' Now the harder method.
Dim expression2 As Expression(Of Func(Of Entity, Boolean)) = Function(e) e.P < "p"

' Reproduce the above using static builder methods.
' Get an expression for our single parameter.
Dim parameter As ParameterExpression = Expression.Parameter(GetType(Entity))

' Get an expression for accessing its P property.
Dim pProperty = Expression.Property(parameter, "P")

' Get a MethodInfo for the string comparison method.
Dim compareMethod As MethodInfo = (From m In GetType(String).GetMethods()
Where m.Name = "Compare" AndAlso m.GetParameters().Count() = 2 AndAlso m.ReturnType = GetType(Integer)
Select m).First()

' Generate our combined lambda.
Dim combinedExpression = CType(
Expression.Lambda(
Expression.Or(
Expression.GreaterThan(Expression.Call(compareMethod, pProperty, Expression.Constant("p")), Expression.Constant(0)),
Expression.LessThan(Expression.Call(compareMethod, pProperty, Expression.Constant("m")), Expression.Constant(0))),
parameter),
Expression(Of Func(Of Entity, Boolean)))

Dim combinedQuery = ctx.Entities.Where(combinedExpression)

Console.WriteLine(combinedQuery.ToString())

Console.Read()
End Sub

End Module

上述示例中的第一个表达式基于 .Where(A AND B) 在逻辑上与 .Where(A).Where(B) 相同>。如上面的示例代码所示,EF 正确地为此生成了良好的 SQL 代码。

上面代码输出的第二个表达式复杂得多。它展示了如何在代码中构建表达式。在这里,因为我们进行了 OR 操作,所以我们无法使用链接 Where() 调用的技巧。

有关问题及其解决方案的精彩讨论,请参阅 this article .

关于entity-framework - 重用包含 SqlFunctions.DatePart 的表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16820381/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com