加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – LINQ to Entities表达式中的对象函数失败

发布时间:2020-12-15 18:23:19 所属栏目:百科 来源:网络整理
导读:请注意:我知道如何解决这个问题.我不是在寻找解决方案,我正在寻找问题本身的清晰度. class Program{ static void Main(string[] args) { using (var context = new TestDbContext()) { var eventsFound = context.Events .Where(e = e.EventDate = DateTime
请注意:我知道如何解决这个问题.我不是在寻找解决方案,我正在寻找问题本身的清晰度.
class Program
{
    static void Main(string[] args)
    {
        using (var context = new TestDbContext())
        {
            var eventsFound = context.Events
                .Where(e => 
                    e.EventDate >= DateTime.Now.AddDays(-1) && 
                    e.EventDate <= DateTime.Now.AddDays(+1)
                )
                .ToList();
        }
    }
}

public class TestDbContext : DbContext
{
    public DbSet<Event> Events { get; set; }
}

public class Event
{
    public int EventId { get; set; }
    public DateTime EventDate { get; set; }
}

好的,所以上面的程序失败了:

LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)'
method,and this method cannot be translated into a store expression.

为什么LINQ不能区分数据库函数和对象函数.系统应该足够聪明,以实现AddDays函数是DateTime对象的一部分.然后它应该首先解析该函数??,然后一旦解析了查询中的所有函数,转换为SQL并对数据库执行该函数.

我确定它比这复杂得多,但我想明白为什么.

=========编辑==============

所以上面并不是一个很好的例子,因为“AddDays”是一个存在于.NET和SQL中的函数.当我将其更改为自定义函数时,如果不存在歧义,该怎么办?

即:

public class Event
{
    public int EventId { get; set; }
    public DateTime EventDate { get; set; }

    public DateTime ReturnDateNowExample()
    {
        return DateTime.Now;
    }
}

static void Main(string[] args)
{
    var myEvent = new Event {EventDate = new DateTime(2013,08,28)};
    using (var context = new TestDbContext())
    {
        var eventsFound = context.Events
            .Where(e =>
                e.EventDate >= myEvent.ReturnDateNowExample()
            )
            .ToList();
    }
}

如果DateTime对象不明确,则替换为string / int对象.

解决方法

其原因与“聪明”无关,更多与Linq的工作方式有关. Linq使用了一种叫做“表达式树”的东西.基本上,它将表达式编译为一组数据,然后由转换层转换为SQL.

这不起作用的原因是因为它在where子句中,并且必须在SQL中执行where子句才能准确.它不能在后端的C#代码中执行,至少不能没有静默地返回表的所有行,这不是一个理想的功能……如果是,你可以告诉它明确地这样做.

实体框架提供了一组函数,用于处理可以直接转换为SQL的日期,这些函数位于EntityFunctions命名空间中.这些映射到所谓的“规范函数”,这意味着SQL有1:1的转换. Linq to Sql将客户端评估的where子句作为参数传递,但这可能是也可能不是所需的值,因为您可能需要服务器端值而不是客户端计算值…因此L2S会给您带来意外导致某些情况.

简而言之,您需要特殊的表达式函数才能转换为SQL,并且遗憾的是,任何旧的标准.NET类都不起作用,而DateTime类也是如此.

您可能会发现以下文章有用:

http://blogs.msdn.com/b/charlie/archive/2008/01/31/expression-tree-basics.aspx

http://tomasp.net/blog/linq-expand.aspx/

http://social.msdn.microsoft.com/Forums/en-US/21a9c660-13e5-4751-aa51-6519bddae044/enterprise-framework-linq-queries-failing

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读