二元表达式无法转换为 LINQ 中的谓词表达式

the binary expression cannot be converted to a predicate expression in LINQ

我想得到某个给定的周数 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 */

说明: 当前网络请求执行过程中出现未处理的异常。请查看堆栈跟踪以获取有关错误及其在代码中的来源的更多信息。

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

我确实在 return q.ToList() 处收到标题错误; .我怎样才能做到这一点?

我从未使用过 LLBLGen library/framework...但这可能与实体 Framework/LINQ-to-SQL 发生的问题相同:您不能输入查询 C# 方法:查询必须由您的数据库服务器执行,而不是在本地执行,并且您的数据库服务器不知道如何执行 C# 代码。所以问题出在 **WeekOf(i.StartDate)** == weeknr 部分代码(即您查询中唯一的 BinaryExpression

您发布的异常非常清楚,错误点就是我建议的那个。那么原因大概就是我给你的那个

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

如果您使用的是支持 DATEPART(isowk, ...) 的 SQL 服务器(或者如果您有 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

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

您可以尝试使您的 WeekOf 方法采用 string 而不是 Datetime?

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()
        {
        }
    }


}
​