LinqProvider 从两个地方获取数据并合并它们

发布于 2024-09-06 08:26:11 字数 624 浏览 1 评论 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 专家的任何建议。

I have a Linq query that looks something like the following

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 }
;

The Session object interacts with a datasource behind the scenes but it also has an internal cached state which may have changes. When I run a query I would like to query the both the internal cached state AND the datasource and then merge the results together, with the internal cached state taking precendence.

I am using re-linq for the generation of the query against the datasource which is working fine. What I am not sure about is how to also do the query against the internal state using the same Linq query.

There's a call GetAllCached() on Session that I can use instead of Session.CreateLinq if I just wanted to query the internal state. But I'm not sure at which point in my custom provider I can handle handing off to the datasource AND the internal state using GetAllCached().

Any suggestions appreciated from any Linq gurus.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南街女流氓 2024-09-13 08:26:11
        // 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

        // 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);

Modified: 04:51 AM Singapore Time

梦纸 2024-09-13 08:26:11

如果我理解正确的话,您的数据源有一个自定义 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 方面的专家,所以我很想看到其他回复。

If I understand correctly, you have a single custom LINQ provider for your datasource, and a (presumably type-safe) way of getting cached results as well.

In this case, I recommend just using LINQ to Objects to access your cached set. You can use AsEnumerable to "step out" of your custom LINQ provider into LINQ to Objects.

The join brings up a problem, though. Since either of these types may exist in the cache, it's not possible to push logic to the DB. For example, is it possible to have an AccountTransaction in the cache without its Account also being in the cache?

If you allow any situation in the cache (e.g., AccountTransaction without associated Account records), then you have to do the join in memory and not in the db:

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 };

However, if you have more control over your cache, and only allow AccountTransaction objects to be present if their associated Account objects are present, then you can push the join operation to the datasource and do another one in memory, merging the results:

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 });

I think. I am not an expert in LINQ, so I'm curious to see other responses.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文