LINQ转换为列表对象
本文关键字:对象 列表 转换 LINQ | 更新日期: 2023-09-27 18:15:51
我使用以下代码返回一个illist:
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();
但是我一直得到这个错误:
无法强制转换类型为'd__7a
输入"System.Collections.Generic.IList"1[DataXLibrary.DataX]。1[<>f__AnonymousType0
3 '的对象[System. string,System. string,System. string]。
我做错了什么?
如果你想要的是List <你只需要:
IList<DataX> QueryListFromFTP = DataX.GetListFromFTP(FileName).Distinct().ToList();
// Use QueryListFromFTP here.
如果你想要一个不同类型对象的List作为你的。select的结果,那么你需要将结果存储在该类型对象的List中,也就是匿名的
下面这行在c#中创建了一个匿名类型,它与Datax类型不对应:
new { x.user_id, x.date, x.application_ID })
你应该这样修改:
Select(x => new Datax(){User_id = x.user_id, Date = x.date, Application = x.application_ID })
你的代码有两个问题:
您正在将
DataX
对象的List
转换为"匿名类型对象"(new { x.user_id, x.date, x.application_ID }
)。 此对象与试着读一下字里行间,看起来你想要一个不同的
DataX
对象列表,其中的区别是由DataX
对象的属性子集决定的。因此,您必须回答这个问题,如何处理在其他属性中具有不同数据的副本(根据此定义)?你必须抛弃其中的一些。Distinct()
不是合适的工具,因为它只适用于它所应用的IEnumerable的整个对象。
DataX
类型不同,不能自动强制返回到DataX
对象。这几乎就像你需要一个DistinctBy
,其中一个参数给出计算独特性的属性,第二个参数给出一些逻辑来决定选择哪些非独特性的"重复"。但是这可以通过多个IEnumerable方法来实现:GroupBy
和从每个结果组中选择适当的单个项目d的进一步表达式。这里有一个可能的解决方案:
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
*/