内部列表对象上的Linq2Sql管道和过滤器

时间:2009-04-18 23:10:30

标签: asp.net-mvc linq linq-to-sql

我正在使用带有管道/过滤器的Linq2Sql。我的数据库由Accounts和Transactions表组成,其中每个Transaction行都链接到一个Account。

显示帐户时,我想显示帐户及其所有交易。很简单。现在我试图限制/ accounts / 4 / {year} / {month} / {day}显示的交易。

Account a = AccountsRepository.GetAccounts()
               .WithID(id)
               .FilterTransactions(year, month, day)
               .SingleOrDefault();

那么如何编写用于返回帐户的过滤器,还要过滤返回的事务?

当我运行没有FilterTransactions的探查器时,我得到2个sql调用...

exec sp_executesql N'SELECT [t0].[ID], [t0].[BankName], 
[t0].[BankCode], [t0].[CardNumber], [t0].[Locale]
FROM [dbo].[Accounts] AS [t0]
WHERE [t0].[ID] = @p0',N'@p0 int',@p0=1

exec sp_executesql N'SELECT [t0].[ID], [t0].[AccountID], 
[t0].[Date], [t0].[Description], [t0].[Amount]
FROM [dbo].[Transactions] AS [t0]
WHERE [t0].[AccountID] = @p0',N'@p0 int',@p0=1

我的想法是,在过滤器中执行类似(年份的简单示例)

public static IQueryable<Account> FilterTransactions(
this IQueryable<Account> qry, int? year, int? month, int? day)
{
    ...loop through each Account
    a.Transactions = a.Transactions
    .Where(t => t.Date.Year == year);
}

但是,a.Transactions是一个EntitySet,Where返回一个IEnumerable。

另一种解决方案是将帐户返回到我的视图,然后在视图中调用HtmlHelper,该HtmlHelper调用另一个Action来显示Transactions。但是,这会导致1次额外的sql调用,并且还会导致我在显示所需信息时出现问题。

2 个答案:

答案 0 :(得分:0)

在相同的SQL连接和相同的datacontext对象中,获取帐户信息的SQL调用和获取事务的set操作几乎是不可避免的。根据我的理解,您基本上必须编写一个返回两个表结果的sproc,然后将讨厌的结果解释回您想要的两条信息。

也许比我更聪明的人可以用Linq做到这一点,我知道你可以直接在SQL中做到这一点。

答案 1 :(得分:0)

相反,我决定通过创建一个包含Account对象和事务列表的ViewModel来实现不同的方法。事务已在同一操作中过滤。由于延迟加载,除非您对它们进行迭代,否则永远不会调用实际Account对象上的Entity事务。