1

我正在尝试返回一组不同的结果,这些结果首先使用 Substring 进行修剪,但是当我调用“Select”时,它会将其转换为匿名类型。我似乎无法让它维持“列表”类型。我只需要返回 Select 方法中指定的字段。

public List<Facility> GetFacilities() {
    var facilities = new List<Facility>(); 
    facilities = _facilityRepository.GetAll().ToList();
    var facReturnList = 
        facilities.Where(x => x.Fac_Name = "Something")
                  .OrderBy(x => x.Fac_Name).ToList();

    var facReturnList2 = 
        facReturnList.Select(x => 
            new { ID = x.Fac_Name.Substring(0, 6), 
                  Fac_Name = x.Fac_Name.Substring(0, 3) })
            .Distinct().ToList();
    return facReturnList2;
}

我尝试List<Facility>在之后添加new,但它说这些属性 (IDFac_Name) 没有在 Facility.xml 中定义。

4

4 回答 4

3

您正在获得匿名类型,因为您正在创建它。

.Select(x => new {

如果你不想那样,就不要那样做。

如果现有类型已经具有您需要的名称和精确属性,请使用它。如果没有类型满足您的需求,请创建一个。然后您可以返回该类型的正确列表或枚举。

.Select(x => new YourDefinedType { 
于 2013-03-08T18:01:11.473 回答
3

你想Facility用你的结果初始化新实例吗?

var facReturnList2 = facReturnList.Select(x => new Facility { ID =   // ...
                                                   ^ concrete type initializer

对编辑的响应:在Select运算符内部,您需要指定要初始化的元素的类型,而不是它们的列表。您之前的代码似乎表明在Fac_Name 定义Facility,但显然不会在 中定义List<Facility>

于 2013-03-08T18:01:26.343 回答
2

听起来你真正想要的是一种DistinctBy方法。您想指定某种方式来表明一个对象是不同的,但您不希望结果是该选择的集合,您希望最终结果是起始对象。LINQ 没有DistinctBy内置的,但实现一个很容易:

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer = null)
{
    comparer = comparer ?? EqualityComparer<TKey>.Default;
    HashSet<TKey> knownKeys = new HashSet<TKey>(comparer);
    foreach (TSource element in source)
    {
        if (knownKeys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
}

使用它,您的代码现在可以变成:

public List<Facility> GetFacilities()
{
    return _facilityRepository.GetAll()
        .Where(x => x.Fac_Name == "Something")
        .DistinctBy(x => new
        {
            ID = x.Fac_Name.Substring(0, 6),
            Fac_Name = x.Fac_Name.Substring(0, 3)
        })
        .OrderBy(x => x.Fac_Name)
        .ToList();
}

如果您有一个IQueryable与内存数据集相反的数据集,您可以使用它GroupBy来获得相同的行为。在 Linq-to-objects 中,使用GroupBy效率会低很多,但对于查询提供程序来说,它不会因为数据库能够优化这一点。

public List<Facility> GetFacilities()
{
    return _facilityRepository.GetAll()
        .Where(x => x.Fac_Name == "Something")
        .OrderBy(x => x.Fac_Name)
        .GroupBy(x => new
        {
            ID = x.Fac_Name.Substring(0, 6),
            Fac_Name = x.Fac_Name.Substring(0, 3)
        })
        .Select(group => group.First())
        .ToList();
}
于 2013-03-08T18:05:23.830 回答
1

以下代码指示 linq 返回匿名类型:

.Select(x => new { ID = x.Fac_Name.Substring(0, 6), Fac_Name = x.Fac_Name.Substring(0, 3) }

您需要为结果创建一个类

public class Result{
    public string ID { get;set; }
    public string Fac_Name { get; set; }
}

//Then do

.Select(x => new Result { ID = x.Fac_Name.Substring(0, 6), Fac_Name = x.Fac_Name.Substring(0, 3) }

这确保您只返回您需要的信息

于 2013-03-08T18:01:28.870 回答