23

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

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

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

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

•Obtics:obtics.codeplex.com

4

6 回答 6

26

它们是这两个包都试图解决的两个问题:缺少 CollectionChanged 事件和动态结果集。还有一个额外的问题可绑定解决,额外的自动事件触发器。


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

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

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

from item in theSource select item ;

当您将 .asBindable 添加到查询源对象时,可绑定 LINQ会执行此操作:

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,您可以修改theSource,并且theResultSet将自动包含新项目。

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 将检测到查询依赖于 TextBox 对象 textBox1 的 Text 属性。由于 TextBox 是 WPF 控件,因此 Bindable LINQ 知道订阅控件上的 TextChanged 事件。

最终结果是,当用户键入时,查询中的项目会被重新评估,并且更改会出现在屏幕上。处理事件不需要额外的代码。

于 2008-10-06T16:05:26.427 回答
6

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

它解决了第一个问题和第二个问题以及其他问题,并将反应性提升到了非常深的水平(具有基于 LINQ 的光线跟踪器的演示)。

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

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

var theResultSet = ExpressionObserver.Execute(
    () => from item in theSource where item.Age > 25 select item
).Cascade();
于 2009-03-03T14:26:58.167 回答
5

要记住的另一件事是,尽管 BindableLinq 需要在 LINQ 语句中调用“.AsBindable()”,但 CLINQ 要求您使用 ContinuousCollection<T> 而不是 ObservableCollection<T>。在简单地看了两者之后,我想我将使用可绑定的 LINQ。

于 2008-12-11T19:45:26.143 回答
5

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

于 2009-02-04T17:27:33.180 回答
1

使用可绑定 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
于 2012-08-28T15:58:21.573 回答
-1

我认为可绑定 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库添加到问题列表中(在 Obtics 之后)。

于 2019-11-20T09:29:27.393 回答