LINQ转换为List对象

时间:2015-10-02 22:47:49

标签: c# linq

我使用以下代码返回IList:

FileName = Path.GetFileName(files[i]);
IList<DataX> QueryListFromFTP = DataX.GetListFromFTP(FileName);
QueryListFromFTP = (IList<DataX>)QueryListFromFTP
    .Select(x => new { x.user_id, x.date, x.application_ID })
    .ToList()
    .Distinct();

但是我一直收到这个错误:

  

无法转换类型&#39; d__7a 1[<>f__AnonymousType0 3 [System.String,System.String,System.String]]&#39;输入&#39; System.Collections.Generic.IList`1 [DataXLibrary.DataX]&#39;。

我做错了什么?

3 个答案:

答案 0 :(得分:0)

以下行在c#中创建一个匿名类型,该类型与Datax类型无关:

System.out

你应该把它改成这样的东西:

new { x.user_id, x.date, x.application_ID })

答案 1 :(得分:0)

如果您想要的是List&lt; DataX&gt;比你所需要的只是:

IList<DataX> QueryListFromFTP = DataX.GetListFromFTP(FileName).Distinct().ToList();
// Use QueryListFromFTP here.

如果你想要一个不同类型的对象的列表作为你的.Select的结果,那么你需要将结果存储在该类型的对象列表中,即匿名的,如果你想要的话。< / p>

答案 2 :(得分:0)

您的代码中存在两个问题:

  1. 您正在将ListDataX个对象转换为“匿名类型对象”(new { x.user_id, x.date, x.application_ID })。此对象与DataX的类型不同,并且无法自动强制转换回DataX对象。

  2. 尝试稍微阅读这些行,看起来您需要一个明确的DataX个对象列表,其中,清晰度由DataX对象的属性子集决定。因此,您必须回答这个问题,对于在其他属性中具有不同数据的重复项(通过此定义),您将如何处理?你必须丢弃其中一些。 Distinct()不是正确的工具,因为它只适用于它所应用的IEnumerable的整个对象。

  3. 这几乎就像你需要一个DistinctBy一个参数给出属性来计算清晰度,第二个参数给出一些逻辑来决定选择哪个非独特的“重复”。但是这可以通过多个IEnumerable方法实现:GroupBy和另一个表达式,用于从每个结果组中选择适当的单个项目。这是一个可能的解决方案:

    FileName = Path.GetFileName(files[i]);
    IList<DataX> QueryListFromFTP = DataX.GetListFromFTP(FileName)
       .GroupBy(datax => new { datax.user_id, datax.date, datax.application_ID })
       .Select(g => g.First()); // or another expression to choose one item per group
       .ToList();
    

    例如,如果有一个version字段,并且您想要每个“重复”的最新字段,您可以:

    .Select(g => g.OrderByDescending(datax => data.version).First())
    

    但请注意,如果您只想要对象的所有属性进行区分,并且不需要选择一个特定值(为了在抛弃一些被认为是重复的对象后获取其附加属性),那么它可能就像这样简单:

    IList<DataX> QueryListFromFTP = DataX.GetListFromFTP(FileName)
       .Distinct()
       .ToList();
    

    我还建议您尽可能使用IReadOnlyCollection.ToList().AsReadOnly()),根据您的数据,您可能希望GetListFromFTP函数执行重复数据删除/清晰度。

    要回答GroupBy不是正确答案的任何问题,因为它可能表现不佳,这是另一种处理此问题的方法(虽然我全心全意地不同意你 - 直到测试证明它很慢,这是一个非常好的答案。)

    // in a static helper class of some kind
    public static IEnumerable<T> DistinctBy<T, TKey>(
        this IEnumerable<T> source,
        Func<T, TKey> keySelector
    ) {
       if (source == null) {
          throw new ArgumentNullException("source", "Source enumerable cannot be null.");
       }
       if (keySelector == null) {
          throw new ArgumentNullException("keySelector", "keySelector function cannot be null. To perform a generic distinct, use .Distinct().");
       }
       return DistinctByImpl(source, keySelector);
    }
    
    private static IEnumerable<T> DistinctByImpl<T, TKey>(
        this IEnumerable<T> source,
        Func<T, TKey> keySelector
    ) {
       HashSet<TKey> keys = new HashSet<TKey>();
       return source.Where(s => keys.Add(keySelector(s)));
    }
    

    它的用法如下:

    public class Animal {
       public string Name { get; set; }
       public string AnimalType { get; set; }
       public decimal Weight { get; set; }
    }
    
    IEnumerable<Animal> animals = new List<Animal> {
        new Animal { Name = "Fido", AnimalType = "Dog", Weight = 15.0M },
        new Animal { Name = "Trixie", AnimalType = "Dog", Weight = 15.0M },
        new Animal { Name = "Juliet", AnimalType = "Cat", Weight = 12.0M },
        new Animal { Name = "Juliet", AnimalType = "Fish", Weight = 1.0M }
    };
    
    var filtered1 = animals.DistinctBy(a => new { a.AnimalType, a.Weight });
    /* returns:
    Name   Type Weight
    Fido   Dog  15.0
    Juliet Cat  12.0
    Juliet Fish 1.0
    */
    
    var filtered2 = animals.DistinctBy(a => a.Name); // or a simple property
    
    /* returns:
    Name   Type Weight
    Fido   Dog  15.0
    Trixie Dog  15.0
    Juliet Cat  12.0
    */