编写一个简单的 LINQ 查询

本文关键字:简单 LINQ 查询 一个 | 更新日期: 2023-09-27 18:34:19

所以我一直生活在迭代数据并以老式方式找到我感兴趣的内容的黑暗时代,但这个项目我认为我应该让事情变得更优雅,并在我知道可以使用的地方使用 LINQ,但事情并不完全点击。

所以我有两个简单的 ObservableCollections,我想从其中一个中提取所有数据,与另一个的当前选定项匹配。 对象非常简单...

public class foo
{
    //....
    public string barID{ get; set; }
    //....
}
public class bar
{
    public string ID { get; set; }
    //....
}

所以在我的代码中,我有选择的 foo,我想创建一个具有匹配 barID 的所有柱的集合......

ObservableCollection<bar> bars = 
    from data in fooCollection
    where data.barID == barCollection.SelectedItem.ID
    select data;

因此,我根据我在网上找到的 LINQ 语法尝试了此操作,但这引发了无法将 IEnumerable 隐式转换为 ObservableCollection 的编译错误。 所以我试了...

ObservableCollection<bar> bars = 
    (ObservableCollection<bar>)
    (from data in fooCollection
    where data.barID == barCollection.SelectedItem.ID
    select data);

哪个编译但抛出运行时错误...

Unable to cast object of type 
'WhereEnumerableIterator`1[TestProj.bar]' to type 
'System.Collections.ObjectModel.ObservableCollection`1[TestProj.bar]'.
因此,

我确信我可以在事后强制转换对象或执行其他操作,但我正在寻找尽可能优雅的解决方案,因此请帮助将这个简单的 LINQ 语句组合在一起。 此外,对幕后发生的事情的简单解释将极大地帮助我理解一些 LINQ 基础知识。

编写一个简单的 LINQ 查询

您只需使用 ObservableCollection 构造函数。

IEnumerable<bar> barEnumerable = 
    from data in fooCollection
    where data.barID == barCollection.SelectedItem.ID
    select data;
ObservableCollection<bar> bars = new ObservableCollection<bar>(barEnumerable);

基本上是这样的:

IEnumerable<bar> barEnumerable = 
fooCollection.Where(data => data.barID == barCollection.SelectedItem.ID);

强制转换会更改表达式的类型,如果表达式确实是该类型,它将起作用。

考虑class Customer : Person

Customer c = new Customer();
Person p = c;  //no problem;  this is an implicit up-cast (from child to parent)
Customer c2 = p;  //compiler doesn't allow because
                  //p may refer to a Person instance that isn't a Customer
Customer c3 = (Customer) p; //we certify to the compiler that p is referencing
                            //a Customer instance, and we take responsibility
                            //for an exception if we are wrong.
                            // this is a down-cast (from parent to child)
Customer cSafe = p as Customer; //safe down-cast, we get a null in cSafe if we are wrong

由于可能存在异常,在我的代码中,向下转换极为罕见。 让我们花点时间感谢泛型使这成为可能。 好的,关于转换:

转换从旧实例创建所需类型的新实例。

Customer c4 = new Customer(p); //conversion constructor
Customer c5 = p.ToCustomer(); //conversion method
Customer c6 = (Customer) p; // if defined, implicit conversion. Otherwise, casting
                            // yes, casting and implicit conversion are the same syntax
                            // terribly confusing.

我们从异常消息中知道,查询返回的实例是一个WhereEnumerableIterator<TestProj.bar>

这个结果实例不是数组,不是List<T>,也不是ObservableCollection<T>。 演员表不起作用,因为ObservableCollection<T>不会从WhereEnumerableIterator<T>继承。 如果您想从中获得ObservableCollection<T>,则需要转换。

语法后面,该查询正在调用Enumerable.Where (msdn(,它返回一个IEnumerable<T> 。 从该类型转换为所需类型的最简单方法是使用 ObservableCollection<T> 的构造函数。

您可以简单地使用"var"作为柱线类型:

var bars = from data in fooCollection
where data.barID == fooCollection.SelectedItem.ID
select data;