EF Core泛型方法中List转IEnumerable<T>失败问题求助
问题解决:EF Core ValueComparer 类型转换错误
错误根源在于ValueComparer的克隆委托返回了List<StringWithStyle>实例,但泛型参数T可能是任意实现IEnumerable<StringWithStyle>的类型(比如数组、自定义集合等),C#无法将List隐式转换为未知的T。
下面提供两种可行的解决方案:
方案1:利用Json序列化实现通用克隆(推荐)
借助已使用的JsonSerializer进行序列化再反序列化,这种方式无需依赖T的构造函数,支持所有Json可序列化的集合类型(包括List、数组、自定义集合):
public static void StringWithStyleConversion<T>(this PropertyBuilder<T> builder) where T : class, IEnumerable<StringWithStyle> { builder.HasConversion( v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), v => JsonSerializer.Deserialize<T>(v, (JsonSerializerOptions)null), new ValueComparer<T>( (arr1, arr2) => arr1.Count() == arr2.Count() && !arr1.Except(arr2).Any(), c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), c => JsonSerializer.Deserialize<T>(JsonSerializer.Serialize(c, (JsonSerializerOptions)null), (JsonSerializerOptions)null) ) ); }
方案2:通过Activator构造T实例(需T满足构造函数要求)
如果确保所有使用的T都有一个接受IEnumerable<StringWithStyle>的构造函数(比如List<StringWithStyle>),可以用反射创建实例:
public static void StringWithStyleConversion<T>(this PropertyBuilder<T> builder) where T : class, IEnumerable<StringWithStyle> { builder.HasConversion( v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), v => JsonSerializer.Deserialize<T>(v, (JsonSerializerOptions)null), new ValueComparer<T>( (arr1, arr2) => arr1.Count() == arr2.Count() && !arr1.Except(arr2).Any(), c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())), c => (T)Activator.CreateInstance(typeof(T), c) ) ); }
注意:方案2不支持数组类型(比如
StringWithStyle[]),因为数组的构造函数不接受集合参数,若需支持数组,需额外添加数组类型的判断处理。
内容的提问来源于stack exchange,提问作者Timothy
相关产品推荐
相关产品推荐

