Linq-to-SQL中的奇怪异常

时间:2016-02-06 18:19:23

标签: c# linq-to-sql

我开发了扩展方法:

public static IQueryable<T> Get<T>(this DataContext dataContext) where T : class
{
    return dataContext.GetTable<T>();
}

然后我尝试使用它:

dataContext.Get<XDbCurrency>().
Where(c => c.Id == XCurrencyId.USD).
SelectMany(
    c =>
        dataContext.Get<XDbCurrencyRate>().
        Where(cr =>
            cr.CurrencyId == c.Id &&
            cr.StartOn <= DateTime.UtcNow &&
            cr.EndOn > DateTime.UtcNow).
        Take(1),
    (c, cr) => cr).
ToArray();

我收到异常Member access 'XCurrencyId CurrencyId' of 'X.XDbCurrencyRate' not legal on type 'System.Data.Linq.Table``1[X.XDbCurrencyRate].当我将Get更改回GetTable时 - 一切正常!当我将Get的返回类型从IQueryable<T>更改为Table<T>时,它会崩溃。

更新。我创建了XDataContextBase类,移动了Get方法,从XDataContext继承了DBML生成的XDataContextBase - 遗憾的是它没有救命。魔法!!

更新。 this.GetTable<XDbCurrencyRate>有效,this.XDbCurrencyRates无效,this.Get<XDbCurrencyRate>不起作用Get是基类中的扩展方法或方法。顺便说一下,内部this.XDbCurrencyRates的实现与Get完全相同。魔法!!

UPDATE。看起来Linq-to-SQL只支持两件事:直接调用DataContext.GetTable<>或调用返回System.Data.Linq.Table<XDbCurrencyRate>的任何命名属性。如果我创建System.Data.Linq.Table<XDbCurrencyRate> Foo - 它可以正常运行,但是当我创建IQueryable<XDbCurrencyRate> Foo时 - 它会与Queries with local collections are not supported.崩溃。魔法!!

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

这是因为初始Get调用不是查询树的一部分。只是一个普通的方法调用。第二个调用嵌入在树中,LINQ to SQL不知道该方法的含义。

我知道EF会立即放弃。我相信L2S基本上能够在本地运行这样的方法并尝试内联它返回的查询。在这里,这似乎现在已经解决了(或者我错了)。

我所做的是创建一个自定义LINQ提供程序,它重写表达式树以在本地执行此类方法,将其结果内联到查询树中,然后转发到LINQ to SQL。这不是微不足道的。

也许你可以从所谓的“LINQ工具包”(近似拼写)中做出AsExpandable