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

时间:2015-05-18 07:16:28

标签: c# linq llblgenpro

我想获得某个给定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 */

说明:执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

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

我在返回q.ToList()时得到标题错误; 。我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:3)

我还没有使用LLBLGen库/框架......但是这可能是与Entity Framework / 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

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

答案 1 :(得分:0)

您可以尝试使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();
            }
        }

答案 2 :(得分:0)

尝试这样的事情

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


}
​