0

我有一个类似于以下内容的 Linq 查询

var query3 = from c in Session.CreateLinq<AccountTransaction>()
             join a in Session.CreateLinq<Account>() on c.Account equals a
             where c.DebitAmount >= 0
             select new { a.Name, c.DebitAmount }
;

Session 对象在幕后与数据源交互,但它也有一个内部缓存状态,可能会发生变化。当我运行查询时,我想查询内部缓存状态和数据源,然后将结果合并在一起,内部缓存状态优先。

我正在使用 re-linq 生成对工作正常的数据源的查询。我不确定的是如何使用相同的 Linq 查询对内部状态进行查询。

如果我只想查询内部状态,可以在 Session 上调用 GetAllCached() 来代替 Session.CreateLinq。但是我不确定在我的自定义提供程序中的哪一点我可以使用 GetAllCached() 处理传递给数据源和内部状态的问题。

任何 Linq 大师的任何建议表示赞赏。

4

2 回答 2

2
        // From Database
        var query1 = from c in Session.CreateLinq<AcccountTransaction>()
                     join a in Session.CreateLinq<Account>()
                     on c.Account equals a
                     where c.DebitAmount >= 0
                     select new { Account = a, AccountTrans = c };
                     //select new { a.Name, c.DebitAmount }; 

        // From Cache
        var query2 = from c in Session.GetAllCached<AcccountTransaction>()
                     join a in Session.GetAllCached<Account>()
                     on c.Account equals a
                     where c.DebitAmount >= 0
                     select new { Account = a, AccountTrans = c };
                     //select new { a.Name, c.DebitAmount };   



        //var query3 = query2.Union(query1.Except(query2));
        var query4 = query2.Union(query1);

修改时间:新加坡时间 04:51 AM

于 2010-06-18T18:47:09.053 回答
1

如果我理解正确,您的数据源有一个自定义 LINQ 提供程序,并且还有一种(可能是类型安全的)获取缓存结果的方式。

在这种情况下,我建议只使用 LINQ to Objects 来访问您的缓存集。您可以使用AsEnumerable将自定义 LINQ 提供程序“跳出”到 LINQ to Objects 中。

但是,这join带来了一个问题。由于这两种类型中的任何一种都可能存在于缓存中,因此无法将逻辑推送到数据库。例如,是否有可能在缓存中有一个AccountTransaction而不Account在缓存中?

如果您允许缓存中有任何情况(例如,AccountTransaction没有关联的Account记录),那么您必须在内存中而不是在数据库中进行连接:

var allDebitAccountTransactions = Session.GetAllCached<AccountTransaction>()
    .Where(x => x.DebitAmount >= 0)
    .Union(Session.CreateLinq<AccountTransaction>()
        .Where(x => x.DebitAmount >= 0));
var allAccounts = Session.GetAllCached<Account>()
    .Union(Session.CreateLinq<Account>());
var query3 = from c in allDebitAccountTransactions
             join a in allAccounts where c.Account equals a
             select new { a.Name, c.DebitAmount };

但是,如果您对缓存有更多控制权,并且仅AccountTransaction在存在关联Account对象时才允许对象存在,那么您可以将join操作推送到数据源并在内存中执行另一个操作,合并结果:

var datasourceResults = from c in Session.CreateLinq<AccountTransaction>()
    join a in Session.CreateLinq<Account>() on c.Account equals a
    where c.DebitAmount >= 0
    select new { a.Name, c.DebitAmount, c.Id };
var cacheResults = from c in Session.GetAllCached<AccountTransaction>()
    join a in Session.GetAllCached<Account>() on c.Account equals a
    where c.DebitAmount >= 0
    select new { a.Name, c.DebitAmount, c.Id };
var query3 = cacheResults.Union(datasourceResults)
    .Select(x => new { x.Name, x.DebitAmount });

我认为。我不是LINQ 方面的专家,所以我很想看到其他回复。

于 2010-06-18T17:26:04.807 回答