代码之家  ›  专栏  ›  技术社区  ›  Muhammad Adeel Zahid

在LINQ查询中使用自定义函数

  •  2
  • Muhammad Adeel Zahid  · 技术社区  · 15 年前

    我在我的ASP.NET MVC应用程序中使用L2S进行数据库操作,在我的存储库中有以下简单查询

    (from pt in db.oaProjectTasks
                       where pt.ProjectID == ProjectID
                       join t in db.oaTasks on pt.TaskID equals t.TaskID
                       where t.ParentTaskID == null
                       let daypassed = GetDaysPassed(t.StartDate,t.Duration)
                       select new ChartTask{TaskNumber = t.TaskNumber,StartDate = t.StartDate,
                       DurationRemaining = t.Duration - daypassed,TaskDescription = t.Task, DaysPassed = daypassed,Duration = t.Duration }).ToList();
    

    下面是GetDayPassed方法的定义

    private int GetDaysPassed(DateTime StartDate, int Duration) 
            {
                int retVal;
                if ((DateTime.Now - StartDate).Days > 0)
                {
                    if ((DateTime.Now - StartDate.AddDays(Duration)).Days > 0)
                    {
                        retVal = Duration;
                    }
                    else
                    {
                        retVal = (DateTime.Now - StartDate).Days;
                    }
                }
                else 
                {
                    retVal = 0;
                }
                return retVal;
            }
    

    但是,没有编译时错误,当我执行代码时,它给了我InvalidOperationException,并显示以下消息。

    Could not translate expression 'Table(oaProjectTask).Where(pt => (pt.ProjectID == Invoke(value(System.Func`1[System.Int64])))).Join(Table(oaTask), pt => pt.TaskID, t => t.TaskID, (pt, t) => new <>f__AnonymousType5f`2(pt = pt, t = t)).Where(<>h__TransparentIdentifier2 => (<>h__TransparentIdentifier2.t.ParentTaskID == null)).Select(<>h__TransparentIdentifier2 => new 
    

    我怎么能避开这个?如果不允许在查询中调用方法,如何在Linq查询中进行简单计算而不是调用GetDayPassed方法?

    1 回复  |  直到 12 年前
        1
  •  5
  •   Branislav Abadjimarinov Ivan Choo    15 年前

    您可以尝试以下操作:

    (from pt in db.oaProjectTasks
     where pt.ProjectID == ProjectID
     join t in db.oaTasks on pt.TaskID equals t.TaskID
     where t.ParentTaskID == null
     select t)
        .ToList() // T-SQL query will be executed here and result will be returned
        .Select(t => new ChartTask {
           TaskNumber = t.TaskNumber,
           StartDate = t.StartDate,
           DurationRemaining = t.Duration - GetDaysPassed(t.StartDate,t.Duration),
           TaskDescription = t.Task, 
           DaysPassed = GetDaysPassed(t.StartDate,t.Duration),
           Duration = t.Duration });
    

    问题是Linq to SQL试图将您的自定义函数转换为T-SQL,因为它不知道如何转换,所以它将抛出异常。在我的例子中,linq将构造查询,执行它(在调用.tolist()之后),并且您的函数将作为linq to objects查询进行调用。