在LINQ中,二进制表达式不能转换为谓词表达式

本文关键字:表达式 不能 转换 谓词 二进制 LINQ | 更新日期: 2023-09-27 17:49:28

我想获得某给定DateTime的周数。

public static int WeekOf(DateTime? date)
            {
                if (date.HasValue)
                {
                    GregorianCalendar gCalendar = new GregorianCalendar();
                    int WeekNumber = gCalendar.GetWeekOfYear(date.Value, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
                    return WeekNumber;
                }
                else
                    return 0;
            }

然后在

中使用上面的方法
public static List<ExpressionListDictionary> MyMethod(int weeknr)
        {
            using (DataAccessAdapter adapter = CreateAdapter())
            {
                LinqMetaData meta = new LinqMetaData(adapter);
                var q = (from i in meta.Test
                         where WeekOf(i.StartDate) == weeknr
                         select new ExpressionListDictionary()
                             {                                 
                                {"SomeId", i.Id}
                             }
                );
                return q.ToList();
            }
        }

最后:

    List<ExpressionListDictionary> someIDs =  MyMethod(weeknr);
/* weeknr = 19 -> step by step debugging */

Description:当前web请求执行过程中发生未处理的异常。请查看堆栈跟踪以获得有关错误及其在代码中的起源位置的更多信息。

异常详细信息: SD.LLBLGen.Pro.ORMSupportClasses.ORMQueryConstructionException:二进制表达式'(WeekOf(Convert(EntityField(LPLA_1. lpl_1 . lpl_1 . ormqueryconstructionexception) 'StartDate AS StartDate)))) == 19)'不能转换为谓词表达式。

我得到标题错误在return q.ToList();. 我怎样才能做到这一点呢?

在LINQ中,二进制表达式不能转换为谓词表达式

我从来没有使用过LLBLGen库/框架…但可能这是同样的问题,发生与实体框架/LINQ-to-SQL:你不能把查询c#方法:查询必须由你的数据库服务器执行,而不是本地,你的数据库服务器不知道如何执行c#代码。所以问题是**WeekOf(i.StartDate)** == weeknr部分代码(这是您的查询中唯一的BinaryExpression)

你所张贴的例外情况很清楚,错误的点是我所建议的。那原因可能就是我给你的那个。

摘自https://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=22861

如果你使用的是SQL Server,它支持DATEPART(isowk, ...)(或者如果你有MySQL,它支持WEEK(...))

public class SQLFunctionMappings : FunctionMappingStore
{
    public SQLFunctionMappings()
    {
        Add(new FunctionMapping(
            typeof(SQLFunctions),
            "WeekOf",
            1,
            "DATEPART(isowk, {0})") // For SQL Server
            // "WEEK({0}, 1)") For MySQL
        );
    }
}
public class SQLFunctions
{
    public static int? WeekOf(DateTime? date)
    {
        return null;
    }
}

,然后你可以这样使用:

LinqMetaData meta = new LinqMetaData(adapter)的行,添加:

meta.CustomFunctionMappings = new SQLFunctionMappings();
并更改where:
where SQLFunctions.WeekOf(i.StartDate) == weeknr

这里是llblgen已经映射的函数列表,以及如何映射其他函数

你可以尝试使用string代替Datetime?的WeekOf方法

public static int WeekOf(String dateAsString)
            {
               //if (!string.IsNullOrEmpty(dateAsString))
                if (!dateAsString.equals(string.empty))
                {
                    GregorianCalendar gCalendar = new GregorianCalendar();
                    int WeekNumber = gCalendar.GetWeekOfYear(date.Value,  CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
                    return WeekNumber;
                }
                else
                    return 0;
            }

然后使用下面的:

public static List<ExpressionListDictionary> MyMethod(int weeknr)
        {
            using (DataAccessAdapter adapter = CreateAdapter())
            {
                LinqMetaData meta = new LinqMetaData(adapter);
                var q = (from i in meta.Test
                         where i.startDate != null && WeekOf(i.StartDate.tostring()) == weeknr
                         select new ExpressionListDictionary()
                             {                                 
                                {"SomeId", i.Id}
                             }
                );
                return q.ToList();
            }
        }

试试这样

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyMethod(5);
        }
        public static int WeekOf(DateTime? date)
        {
            if (date.HasValue)
            {
                GregorianCalendar gCalendar = new GregorianCalendar();
                int WeekNumber = gCalendar.GetWeekOfYear(date.Value, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
                return WeekNumber;
            }
            else
                return 0;
        }
        public static List<ExpressionListDictionary> MyMethod(int weeknr)
        {
            using (DataAccessAdapter adapter = CreateAdapter())
            {
                LinqMetaData meta = new LinqMetaData(adapter);
                List<ExpressionListDictionary> q = (from i in meta.Test
                         where WeekOf(i.StartDate) == weeknr
                         select new ExpressionListDictionary()
                         {
                                Id = "SomeId"
                         }
                ).ToList();
                return q;
            }
        }
        public static DataAccessAdapter CreateAdapter()
        {
            return new DataAccessAdapter();
        }
    }
    public class ExpressionListDictionary
    {
        public string Id { get; set; }
    }
    public class LinqMetaData
    {
        public List<LinqMetaData> Test {get;set;}
        public DateTime StartDate {get;set;}
        public int Id { get; set; }
        public LinqMetaData(DataAccessAdapter adapter)
        {
        }
    }
    public class DataAccessAdapter : IDisposable
    {
        public void Dispose()
        {
        }
    }

}
​