可绑定LINQ和连续LINQ之间的主要区别是什么?
•Bindable LINQ:www.codeplex.com/bindablelinq
•连续LINQ:www.codeplex.com/clinq
根据提供的反馈添加了另外一个项目:
•Obtics:obtics.codeplex.com
答案 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中没有提到任何问题。该库可与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之后)。