C# LINQ中的铸造问题(C.NET4)

C# LINQ中的铸造问题(C.NET4),c#,linq,C#,Linq,我遇到了一个非常令人困惑的问题,希望有人能帮我解决。在我的应用程序中,我有以下数据结构: public struct EntityDetails { public string EntityName { get; set; } public List<AttributeDetails> Attributes { get; set; } public bool EntityExists { get; set; } } public struct Attribu

我遇到了一个非常令人困惑的问题,希望有人能帮我解决。在我的应用程序中,我有以下数据结构:

public struct EntityDetails
{
    public string EntityName { get; set; }
    public List<AttributeDetails> Attributes { get; set; }
    public bool EntityExists { get; set; }
}

public struct AttributeDetails
{
    public string AttributeName { get; set; }
    public string DisplayName { get; set; }
    public string DataType { get; set; }
    public string Description { get; set; }
    public bool AttributeExists { get; set; }
}
当我将鼠标悬停在上面时,实际的错误消息是System.ArgumentNullException

使用以下代码:

 return entityList.Where(e => e.EntityName == pEntityName)
                                             .Select(e => e.Attributes
                                                           .Where (a => a.AttributeName
                                                           .Contains (pAttributeFilter))).ToList()
LINQ返回的IEnumerable不是列表,所以不能将此对象强制转换为列表。当您调用ToList时,linq查询将被执行并转换为list,因为您的属性实际上是AttributeDetails的实例,那么您可以在查询结束时调用.ToList。但是,另一种合适的方法是更改方法的签名以返回IEnumerable,这取决于调用方期望的功能

事实上,如果需要,调用方仍然可以在空闲时转换查询结果,您可以可靠地返回进一步的可读和可查询的集合。所以

public static IEnumerable<AttributeDetails> GetFilteredAttributeList(
  string pEntityName, string pAttributeFilter) {
  return entityList
    .Where(e => e.EntityName == pEntityName)
    .Select(e => e.Attributes
      .Where (a => a.AttributeName.Contains (pAttributeFilter)
    )
  );
}
您只需调用将结果转换为列表即可结束LINQ查询

需要记住的一件事是,LINQ查询上的调用.ToList实现了这一点,这意味着执行不再是;结果现在存储在列表的内存中

此外,我相信您希望使用子句,而不是.Select。e、 属性是一个列表。如果使用Select,它将创建一个IEnumarable,其中每个元素都是一个实体的属性。SelectMany将组合返回的列表并返回一个IEnumerable,它似乎就是您想要的

最终,您希望使用以下各项:

public static List<EntityDetails> entityList { get; set; }
return entityList.Where(e => e.EntityName == pEntityName)
                 .SelectMany(e => e.Attributes
                             .Where (a => a.AttributeName
                                     .Contains(pAttributeFilter)))
                 .ToList();
您需要选择Many将属性拖出到单个列表中。您还需要ToList将结果转换为列表。演员阵容将是不必要的

试一试


你真是个天才!非常感谢。我会投票支持你,但显然我需要15个声望才能做到这一点!非常感谢。请用您在@Habib回复中发布的错误更新您的问题。这是我意识到你需要很多的唯一原因。
public static IEnumerable<AttributeDetails> GetFilteredAttributeList(
  string pEntityName, string pAttributeFilter) {
  return entityList
    .Where(e => e.EntityName == pEntityName)
    .Select(e => e.Attributes
      .Where (a => a.AttributeName.Contains (pAttributeFilter)
    )
  );
}
return entityList.Where(e => e.EntityName == pEntityName)
                 .SelectMany(e => e.Attributes
                             .Where (a => a.AttributeName
                                     .Contains(pAttributeFilter)))
                 .ToList();
public static List<AttributeDetails> GetFilteredAttributeList(string pEntityName, string pAttributeFilter)
    {
        var entityList = new List<EntityDetails>(); //added just to makte it compile

        var filtered =
            from entity in entityList
            where entity.EntityName == pEntityName
            from attribute in entity.Attributes
            where attribute.AttributeName.Contains(pAttributeFilter)
            select attribute;
        return filtered.ToList();
    }
return entityList.Where(e => e.EntityName == pEntityName)
                 .SelectMany(e => e.Attributes
                                   .Where (a => a.AttributeName
                                                 .Contains (pAttributeFilter)))
                 .ToList();