可绑定 LINQ 和连续 LINQ 之间的主要区别是什么?
•可绑定LINQ:www.codeplex.com/bindablelinq
• 连续 LINQ:www.codeplex.com/clinq
根据提供的反馈,又添加了一个项目:
•Obtics:obtics.codeplex.com
可绑定 LINQ 和连续 LINQ 之间的主要区别是什么?
•可绑定LINQ:www.codeplex.com/bindablelinq
• 连续 LINQ:www.codeplex.com/clinq
根据提供的反馈,又添加了一个项目:
•Obtics:obtics.codeplex.com
它们是这两个包都试图解决的两个问题:缺少 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 事件。
最终结果是,当用户键入时,查询中的项目会被重新评估,并且更改会出现在屏幕上。处理事件不需要额外的代码。
我可以提请您注意另一个 codeplex 项目吗?它被称为 Obtics 并处理相同的问题 ( http://obtics.codeplex.com )。
它解决了第一个问题和第二个问题以及其他问题,并将反应性提升到了非常深的水平(具有基于 LINQ 的光线跟踪器的演示)。
它声称完全支持所有 LINQ 语句和 Enumerable 类的方法。
它使用另一种机制来创建实时查询:
var theResultSet = ExpressionObserver.Execute(
() => from item in theSource where item.Age > 25 select item
).Cascade();
要记住的另一件事是,尽管 BindableLinq 需要在 LINQ 语句中调用“.AsBindable()”,但 CLINQ 要求您使用 ContinuousCollection<T> 而不是 ObservableCollection<T>。在简单地看了两者之后,我想我将使用可绑定的 LINQ。
确实; Continuous LINQ 的主要问题是无法使用任何实现通用 IEnumerable 和 INotifyCollectionChanged 的集合。可绑定 LINQ 使用实现这两个接口的自定义集合没有问题。
使用可绑定 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
我认为可绑定 LINQ 和连续 LINQ 大致相同:它们提供对 LINQ 计算变化的观察。提供的实现和 API 可能有所不同。看来我的ObservableComputations库涵盖了 Bindable LINQ 和连续 LINQ 预期的功能,并且在https://stackoverflow.com/a/174924/2663791中没有提到任何问题。该库与INotifyPropertyChanged和INotifyCollectionChanged接口一起使用,从而可以直接使用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 之后)。