可绑定LINQ与连续LINQ

时间:2008-10-03 16:08:00

标签: bindable-linq

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

•Bindable LINQ:www.codeplex.com/bindablelinq

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

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

•Obtics:obtics.codeplex.com

6 个答案:

答案 0 :(得分:25)

这些包试图解决它们的两个问题:缺少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,您可以修改 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;
  

Bindable LINQ会检测到   查询依赖于Text的Text属性   TextBox对象,textBox1。以来   TextBox是一个WPF控件,Bindable   LINQ知道订阅   控件上的TextChanged事件。

     

最终结果是作为用户   类型,查询中的项目   重新评估并显示更改   屏幕。无需其他代码   处理事件。

答案 1 :(得分:5)

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

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

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

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

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

答案 2 :(得分:4)

另外要记住的是,尽管BindableLinq在LINQ语句中需要“.AsBindable()”调用,但CLINQ要求您使用ContinuousCollection&lt; T&gt;而不是ObservableCollection&lt; T&gt;。简要地看一下之后,我想我会选择可绑定的LINQ。

答案 3 :(得分:4)

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

答案 4 :(得分: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

答案 5 :(得分:-1)

我认为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库(在Obtics之后)。