Linq 查询变量对象属性集合上的 Where 条件

本文关键字:Where 条件 集合 属性 查询 变量 对象 Linq | 更新日期: 2023-09-27 18:33:30

我正在访问具有以下结构的互操作模型

项目

是包含多个项目对象的集合

项目对象具有 State 属性和属性集合

属性

集合包含变体/对象/属性对象

该属性始终具有 Name 属性

我想使用 Linq 执行以下操作:

查找所有项目 查找第一个属性对象(一个或多个项目可能具有 Property.Name == "发起方名称"。我只想要第一个具有 Property.Name == "IntiatorName" 的属性对象。也就是说,我不在乎属性对象属于哪个项目。

其中项目状态 = state_initiated

以及具有 Project.Name = "发起方名称" 的项目属性

这是我正在尝试的 Linq(C# 不喜欢(...我想我的前几行是正确的,但我不确定如何处理变体属性对象。

我可以在 Linq 中执行哪些操作,还是必须枚举所有属性对象?

var result = dept.Projects
  .Cast<Project>()
  .Where(project => project.State == pState.state_initiated)
  .SelectMany(project => project.Properties())
  .Where(property => property.Name == "InitiatorName");

这是属性接口的互操作签名:

public interface _Properties : IEnumerable
{
    [DispId(1)]
    Application Application { get; }
    [DispId(40)]
    int Count { get; }
    [DispId(2)]
    object Parent { get; }
    [DispId(-4)]
    [TypeLibFunc(1)]
    IEnumerator GetEnumerator();
    [DispId(0)]
    Property Item(object index);
}

属性签名如下所示:

public interface Property
{
    [DispId(41)]
    Properties Collection { get; }
    [DispId(40)]
    string Name { get; }
    [DispId(1)]
    Properties Parent { get; }
    [DispId(0)]
    object Value { get; set; }
}

Linq 查询变量对象属性集合上的 Where 条件

你需要做这样的事情:

var result = dept.Projects
    .Cast<Project>()
    .Where(project => project.State == pState.state_initiated)
    .SelectMany(project => project.Properties().OfType<Property>())
    .FirstOrDefault(property => property.Name == "InitiatorName");

此代码假定Properties是一种Project的方法。

如果是 Project 的属性,则需要使用 .Properties.OfType<Property>() 而不是 .Properties().OfType<Property>()

如果您确定 Properties 仅包含类型 Property 的对象,则可能需要使用 Cast 而不是 TypeOf 可能是这种情况。

通过访问 SelectMany of Properties,您不会根据需要获得项目,而是获得属性。

请尝试以下查询:

var result = dept.Projects
                .Cast<Project>()
                .Where(
                    project =>
                        project.State == pState.state_initiated &&
                        project.Properties().Any(property => property.Name == "InitiatorName"));

"属性(("可能不会提供空值。因此,如果存在可能发生的情况,请通过空检查来处理这种情况。