gpt4 book ai didi

linq - LINQ to SQL EntitySet 中的抽象泄漏

转载 作者:行者123 更新时间:2023-12-03 07:35:02 24 4
gpt4 key购买 nike

我在处理某些 dbml 生成的类时遇到了问题,这些类无法解析为高效的 SQL。想象一下,我有一个帐户表和一个交易表,其中每笔交易都与特定帐户相关联。我将所有这些加载到 dbml 中,然后弹出一个 Account 类和一个 Transaction 类。 Account 类有一个对 Transactions 集合的 EntitySet 引用,代表该账户上的所有交易。很公平。

现在假设我只想要当前会计期间的交易。所以我添加了这样的方法:

public IEnumerable<Transaction> CurrentTransactions
{
get
{
DateTime dtStart = CurrentPeriod;
DateTime dtEnd = NextPeriod;
return
from t in Transactions
orderby t.date
where t.date >= CurrentPeriod && t.date <= NextPeriod
select t;
}
}

看起来不错并且可以工作,但是 SQL 不好:

SELECT [t0].[id], [t0].[account_id], [t0].[date], [t0].[description], [t0].[amount], [t0].[sign]
FROM [dbo].[transactions] AS [t0]
WHERE [t0].[account_id] = @p0

即:它将整个事务集拉下来并使用 LINQ for Objects 进行处理。我尝试去掉 where 子句、orderby 子句,用常量替换日期,这一切仍然在客户端完成。

为了进行比较,我尝试直接从数据上下文调用 Transactions 集合:

DateTime dtStart = account.CurrentPeriod;
DateTime dtEnd = account.NextPeriod;
IEnumerable<Transaction> trans=
from t in MyDataContext.Transactions
orderby t.date
where t.date >= dtStart && t.date <= dtEnd && t.account_id==iAccountID
select t;

而且效果非常好:

SELECT [t0].[id], [t0].[account_id], [t0].[date], [t0].[description], [t0].[amount], [t0].[sign]
FROM [dbo].[transactions] AS [t0]
WHERE ([t0].[date] >= @p0) AND ([t0].[date] <= @p1) AND ([t0].[account_id] = @p2)
ORDER BY [t0].[date]

毕竟,我有两个问题:

  1. 事务实体集的上述行为是否正确和/或是否有解决方法?
  2. 如何在我的 Account 类上将上述“修复”作为方法实现。 dbml 生成的实体类无权访问 DataContext。

最佳答案

遗憾的是,你不能这样做。为 LINQ to SQL 实体类生成的集合属性不是 IQueryable ;因此,对它们执行的任何查询都将使用 LINQ to Objects。这是设计使然。正如您自己正确地注意到的那样,为了获得有效的查询,您必须查询 Transactions取自您的DataContext ,但你的属性 getter 中没有。

此时您的选择是:

  • 使其成为一个采用 DataContext 的方法作为论据;或
  • 使用反射黑客来检索上下文 - 实体本身并不存储它,但 EntitySet确实如此,尽管是间接的 - 当然这是特定于版本的,容易损坏等。

据我所知, Entity Framework 没有这个限制,因为它的集合属性是 ObjectQuery<T> - 即 IQueryable .

关于linq - LINQ to SQL EntitySet 中的抽象泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1469041/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com