【问题标题】:LinqProvider that gets data from from two places and merges them从两个地方获取数据并合并它们的 LinqProvider
【发布时间】:2010-06-18 16:22:24
【问题描述】:

我有一个类似于以下内容的 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 大师的建议。

【问题讨论】:

    标签: c# linq provider


    【解决方案1】:
            // 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

    【讨论】:

    • Except 不是建立优先级所必需的。 Union 将始终为其第一个参数提供优先级。此外,如果任何帐户有两个相同金额的借记交易,此代码将失败。
    • 感谢您的亮点。我做了相应的修改。
    【解决方案2】:

    如果我理解正确,您的数据源只有一个自定义 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 };
    

    但是,如果您对缓存有更多控制权,并且仅在存在关联的Account 对象时才允许存在AccountTransaction 对象,那么您可以将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 方面的专家,所以我很想看看其他回复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-01
      • 2021-02-19
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 2017-11-22
      • 1970-01-01
      • 2021-12-20
      相关资源
      最近更新 更多