【问题标题】:the binary expression cannot be converted to a predicate expression in LINQ无法将二进制表达式转换为 LINQ 中的谓词表达式
【发布时间】:2015-05-18 07:16:27
【问题描述】:

我想获取某个给定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库吗?
  • 是的,我确实在我的项目中使用了 llblgen 库
  • 也许在这种情况下添加括号会有所帮助。比如:where (WeekOf(i.StartDate) == weeknr)

标签: c# linq llblgenpro


【解决方案1】:

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

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

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

如果您使用的是支持DATEPART(isowk, ...) 的SQL Server(或者如果您有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已经映射的函数列表,以及如何映射其他函数。

【讨论】:

  • xanatos,是的,我也认为问题存在......现在,我要回到我最初的问题:如何使用 LINQ,某个给定日期时间的周数?
  • 我可以使用:SqlFunctions.DatePart 吗?但我什至无法解决这个方法,添加一些特定的命名空间......
  • @FlorinM。如果您需要其他 SQL 函数,您可以轻松地使该代码适应其他 SQL 函数。 1, 是要传递的参数个数(所以如果你想在函数中有两个参数,你把2
  • 感谢您的精彩提示和信息。我真的希望这个问题/答案对其他人有所帮助
  • 如果我希望一周从星期日开始(不是星期一)如何修改?
【解决方案2】:

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

【讨论】:

  • 恐怕我不明白,当您将 weeknr(int) 与 weekof(function return int) 进行比较时,无需将 weeknr 更改为字符串。
【解决方案3】:

试试这样的

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


}
​

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多