可绑定 LINQ 与连续 LINQ

发布于 2024-07-06 11:14:47 字数 189 浏览 5 评论 0原文

可绑定 LINQ 和连续 LINQ 之间的主要区别是什么?

•可绑定 LINQ:www.codeplex.com/bindablelinq

•连续 LINQ:www.codeplex.com/clinq

根据提供的反馈又添加了一个项目:

•Obtics:obtics.codeplex.com

What are the major difference between bindable LINQ and continuous LINQ?

•Bindable LINQ: www.codeplex.com/bindablelinq

•Continuous LINQ: www.codeplex.com/clinq

One more project was added basing on the provided feedback:

•Obtics: obtics.codeplex.com

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

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

发布评论

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

评论(6

韵柒 2024-07-13 11:14:47

这些包试图解决两个问题:缺少 CollectionChanged 事件和动态结果集。 还有一个可绑定解决的问题,即附加的自动事件触发器。


这两个包旨在解决的第一个问题是:

LINQ 查询返回的对象
不提供 CollectionChanged 事件。

连续 LINQ 自动对所有查询执行此操作,无需任何更改:

from item in theSource select item ;

Bindable LINQ 在将 .asBindable 添加到查询源对象时执行此操作:

from item in theSource.AsBindable() select item ;

第二个问题

从 LINQ 查询返回的结果集
是静态的。

通常,当您执行 LINQ 查询时,您的结果集不会改变,直到您执行新的查询。 使用这两个包,只要更新,您的结果集就会更新。 (对性能不利,但有利于实时更新)

示例

var theSource = new ContinuousCollection<Customer>();
var theResultSet = from item in theSource where item.Age > 25 select item;
//theResultSet.Count would equal 0.

因为您使用 Bindable 或 Continuous LINQ,您可以修改 theSourcetheResultSet 将自动包含新项目。

theSource.Add(new Customer("Bob", "Barker" , 35, Gender.Male)); //Age == 35
//theResultSet.Count would now equal 1.

附加问题 可绑定的 LINQ 提供:(直接从他们自己的页面引用)

contactsListBox.ItemsSource = from c in customers
                              where c.Name.StartsWith(textBox1.Text)
                              select c;

可绑定 LINQ 将检测到
查询依赖于 Text 属性
TextBox 对象,textBox1。 自从
TextBox是一个WPF控件,可绑定
LINQ 知道订阅
控件上的 TextChanged 事件。

最终的结果是,作为用户
类型,查询中的项目是
重新评估并且更改出现在
屏幕。 不需要额外的代码
处理事件。

Their are 2 problems both these packages try to solve: Lack of a CollectionChanged event and Dynamic result sets. There is one additional problem bindable solves, additional automatic event triggers.


The First Problem both packages aim to solve is this:

Objects returned by a LINQ query do
not provide CollectionChanged events.

Continuous LINQ automatically does this to all queries, with no change:

from item in theSource select item ;

Bindable LINQ does this when you add .asBindable to your query Source Object:

from item in theSource.AsBindable() select item ;

The Second Problem both packages aim to solve is:

Result sets returned from a LINQ Query
are static.

Normally when you do a LINQ Query your result set is unchanged until you do a new query. With these two packages, your result set is updated whenever the source is updated. (bad for performance, good for realtime updates)

Example

var theSource = new ContinuousCollection<Customer>();
var theResultSet = from item in theSource where item.Age > 25 select item;
//theResultSet.Count would equal 0.

Because your using Bindable or Continuous LINQ, you could modify theSource, and theResultSet would automatically include the new item.

theSource.Add(new Customer("Bob", "Barker" , 35, Gender.Male)); //Age == 35
//theResultSet.Count would now equal 1.

The Additional Problem Bindable LINQ offers: (Quoting directly from their own page)

contactsListBox.ItemsSource = from c in customers
                              where c.Name.StartsWith(textBox1.Text)
                              select c;

Bindable LINQ will detect that the
query relies on the Text property of
the TextBox object, textBox1. Since
the TextBox is a WPF control, Bindable
LINQ knows to subscribe to the
TextChanged event on the control.

The end result is that as the user
types, the items in the query are
re-evaluated and the changes appear on
screen. No additional code is needed
to handle events.

勿忘初心 2024-07-13 11:14:47

我可以提请您注意另一个 codeplex 项目吗? 它称为 Obtics,处理相同的问题 (http://obtics.codeplex.com)。

它解决了第一个问题、第二个问题和附加问题,并将反应性提升到非常深的水平(使用基于 LINQ 的光线跟踪器进行了演示)。

它声称完全支持所有 LINQ 语句和 Enumerable 类的方法。

它使用另一种机制来创建实时查询:

var theResultSet = ExpressionObserver.Execute(
    () => from item in theSource where item.Age > 25 select item
).Cascade();

May I draw your attention to another codeplex project? It's called Obtics and deals with the same issues (http://obtics.codeplex.com).

It addresses both the first the second and the additional problem and takes reactivity to a very deep level (has a demonstration with a LINQ based raytracer).

It claims full support for all LINQ statements an methods of the Enumerable class.

It uses yet another mechanism to create live queries:

var theResultSet = ExpressionObserver.Execute(
    () => from item in theSource where item.Age > 25 select item
).Cascade();
赠我空喜 2024-07-13 11:14:47

的确; Continuous LINQ 的主要问题是无法使用任何实现通用 IEnumerable 和 INotifyCollectionChanged 的​​集合。 Bindable LINQ 使用自定义集合实现这两个接口没有问题。

Indeed; the main issue with Continuous LINQ is the inability to use any collection that implements the generic IEnumerable and INotifyCollectionChanged. Bindable LINQ has no problem with using custom collections implementing the two interfaces.

神经暖 2024-07-13 11:14:47

另一件需要记住的事情是,虽然 BindableLinq 需要在 LINQ 语句中调用“.AsBindable()”,但 CLINQ 要求您使用 ContinuousCollection。 而不是 ObservableCollection。 简要查看两者后,我想我将选择可绑定 LINQ。

Another thing to keep in mind, although BindableLinq requires the ".AsBindable()" call in the LINQ statement, CLINQ requires that you use ContinuousCollection<T> instead of ObservableCollection<T>. After looking at both briefly, I think I'm going to go with bindable LINQ.

倾城泪 2024-07-13 11:14:47

使用可绑定的 LINQ,因为它实现了 IDisposable,因此您可以控制何时处理查询。 当您处置它时,所有对 INotifyPropertyChanged 的​​订阅都将取消订阅。

连续 LINQ 应该可以通过弱事件解决这个问题,但据我测试,它不起作用。

嗯...这似乎是可绑定 LINQ 的问题(第二个断言失败):

var _source = CreateSource_6People(); //(David, 27), (Mark, 15), (Steve, 30), (Jordan, 43), (Shiva, 30), (Erb, 43)
IBindable<int> bindable = _source.AsBindable().Sum(x => x.Age);
var agesSum = 27+15+30+43+30+43;
Assert.AreEqual(agesSum, bindable.Current); //PASSES

_source[0].Age += 1;
Assert.AreEqual(agesSum + 1, bindable.Current); //FAILS... DISAPPOINTING

Use bindable LINQ, as it implements IDisposable, and therefore you can control when a query gets disposed. When you dispose it, all the subscriptions to INotifyPropertyChanged will unsubscribe.

Continuous LINQ is supposed to solve this problem with weak events, but it doesn't work as far as I was able to test.

Hmm... this seems to be a problem with bindable LINQ (the second assert fails):

var _source = CreateSource_6People(); //(David, 27), (Mark, 15), (Steve, 30), (Jordan, 43), (Shiva, 30), (Erb, 43)
IBindable<int> bindable = _source.AsBindable().Sum(x => x.Age);
var agesSum = 27+15+30+43+30+43;
Assert.AreEqual(agesSum, bindable.Current); //PASSES

_source[0].Age += 1;
Assert.AreEqual(agesSum + 1, bindable.Current); //FAILS... DISAPPOINTING
篱下浅笙歌 2024-07-13 11:14:47

我认为 Bindable LINQ 和连续 LINQ 大致相同:它们提供对 LINQ 计算变化的观察。 提供的实现和 API 可能有所不同。 看来我的 ObservableComputations 库涵盖了 Bindable LINQ 和连续 LINQ 预期的功能,并且没有 https://stackoverflow.com/a/174924/2663791。 该库可与 INotifyPropertyChangedINotifyCollectionChanged 接口,使得可以使用 ObservableCollection
使用该库,您可以像这样编写代码:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using IBCode.ObservableComputations;

namespace ObservableComputationsExamples
{
    public class Order : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public int Num {get; set;}

        private decimal _price;
        public decimal Price
        {
            get => _price;
            set
            {
                _price = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Price)));
            }
        }

        public Order(int num, decimal price)
        {
            Num = num;
            _price = price;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ObservableCollection<Order> orders = 
                new ObservableCollection<Order>(new []
                {
                    new Order(1, 15),
                    new Order(2, 15),
                    new Order(3, 25),
                    new Order(4, 27),
                    new Order(5, 30),
                    new Order(6, 75),
                    new Order(7, 80),
                });

            //********************************************
            // We start using ObservableComputations here!
            Filtering<Order> expensiveOrders = orders.Filtering(o => o.Price > 25); 

            checkFiltering(orders, expensiveOrders); // Prints "True"

            expensiveOrders.CollectionChanged += (sender, eventArgs) =>
            {
                // see the changes (add, remove, replace, move, reset) here
            };

            // Start the changing...
            orders.Add(new Order(8, 30));
            orders.Add(new Order(9, 10));
            orders[0].Price = 60;
            orders[4].Price = 10;
            orders.Move(5, 1);
            orders[1] = new Order(10, 17);

            checkFiltering(orders, expensiveOrders); // Prints "True"

            Console.ReadLine();
        }

        static void checkFiltering(
            ObservableCollection<Order> orders, 
            Filtering<Order> expensiveOrders)
        {
            Console.WriteLine(expensiveOrders.SequenceEqual(
                orders.Where(o => o.Price > 25)));
        }
    }
}

请将 ObservableComputations 库添加到问题中的列表中(在眼科)。

I think Bindable LINQ and continuous LINQ are about the same: they provides observing for changes in LINQ computation. Implementation and API provided may some differ. It seems my ObservableComputations library covers functionality expected from Bindable LINQ and continuous LINQ and has no problems mentioned in https://stackoverflow.com/a/174924/2663791. That library works with INotifyPropertyChanged and INotifyCollectionChanged interfaces, that makes it possible to operate with ObservableCollection direcly.
Using that library you can code like this:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using IBCode.ObservableComputations;

namespace ObservableComputationsExamples
{
    public class Order : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public int Num {get; set;}

        private decimal _price;
        public decimal Price
        {
            get => _price;
            set
            {
                _price = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Price)));
            }
        }

        public Order(int num, decimal price)
        {
            Num = num;
            _price = price;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            ObservableCollection<Order> orders = 
                new ObservableCollection<Order>(new []
                {
                    new Order(1, 15),
                    new Order(2, 15),
                    new Order(3, 25),
                    new Order(4, 27),
                    new Order(5, 30),
                    new Order(6, 75),
                    new Order(7, 80),
                });

            //********************************************
            // We start using ObservableComputations here!
            Filtering<Order> expensiveOrders = orders.Filtering(o => o.Price > 25); 

            checkFiltering(orders, expensiveOrders); // Prints "True"

            expensiveOrders.CollectionChanged += (sender, eventArgs) =>
            {
                // see the changes (add, remove, replace, move, reset) here
            };

            // Start the changing...
            orders.Add(new Order(8, 30));
            orders.Add(new Order(9, 10));
            orders[0].Price = 60;
            orders[4].Price = 10;
            orders.Move(5, 1);
            orders[1] = new Order(10, 17);

            checkFiltering(orders, expensiveOrders); // Prints "True"

            Console.ReadLine();
        }

        static void checkFiltering(
            ObservableCollection<Order> orders, 
            Filtering<Order> expensiveOrders)
        {
            Console.WriteLine(expensiveOrders.SequenceEqual(
                orders.Where(o => o.Price > 25)));
        }
    }
}

Please, add ObservableComputations library to the list in the question (after Obtics).

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