将 IEnumerable 转换为另一个 IEnumerable C#

Covert IEnumerable to another IEnumerable C#

来自 JS/PHP/Node 背景,对 C# 应用程序开发有些陌生。在 MVC 应用程序上工作。

我需要 return IEnumerable<Car> 的对象从我的服务到我的控制器。我的服务调用我的存储库 returns IEnumberable<CarEntity>

我不知道如何将 CarEntity 列表转换为 Car 列表。

车子长得像

    public int CarId { get; set; }
    public string CarColor { get; set; }
    public string CarMake { get; set; }
    public string CarModel { get; set; }

CarEntity 看起来像

    public int Id { get; set; }
    public string Color { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public string SomeOtherProp { get; set;}

这是一个例子,但这通常是我需要的。我是否需要对我的 CarEntity 列表进行某种循环并将每一个都推送到 Car 列表?我认为有一些更精明的方法可以做到这一点。

是的。您需要为汽车实体列表集合中的每个项目创建一个新的 Car 对象并分配 属性 值。您可以在 foreach 循环中执行此操作

var carEntityList= new List<CarEntity>(); //assume this has items
var carList = new List<Car>();
foreach(car carEntity in carEntityList)
{
  var c= new Car();
  c.CarId =carEntity.Id;
  // to do : Map other property values as well.
  carList.Add(c);     
}

使用方便的 LINQ 扩展方法,例如 IEnumerable.Select

var carEntityList= new List<CarEntity>(); //assume this has items
var carList = carEntityList.Select(s=>new Car { 
                                                CarId = s.Id, 
                                                CarColor = s.Color, 
                                                CarModel = s.Model,
                                                CarMake = s.Make
                                              }
                                  );

长手的方法是使用 LINQ 的 .Select extension method on IEnumerable<T> to project 将一个集合中的项目放入另一个集合中:

IEnumberable<CarEntity> carEntities = repository.GetCars();

IEnumerable<Car> cars = 
    carEntities
    .Select(c => 
         new Car
         {
             CarId = c.Id,
             CarColor = c.Color,
             //etc.
         });

有像 AutoMapper 这样的工具,但我没有使用它们的经验。

假设 resultsIEnumerable<CarEntity>:

 IEnumerable<Car> cars = results.Select(c=> new Car{Brand = c.Brand, Color = c.Color});
List<Car> cars = results.Select(r=> new Car(){CarId = r.Id, CarColor = r.Color .... etc}}).ToList();

results 将是您的 IEnumerable

其实很简单 让我们假设您的 collections 如下

IEnumerable<Car>=cars;
IEnumerable<CarEntity>=entities;

那么您的代码应该 运行 在所有实体上都是这样的:

foreach(CarEntity e in entities){
       Car c = new Car(e.Id,e.Color,e.Make,e.Model);
       cars.Add(c);
}

只是为了输入,如果您有很多实体并且您需要(可能应该)将它们转换为其他边界对象以供不同用途,我会将该映射逻辑放在实体的扩展 class 中。

这是为了不依赖实体 - 以及可能的其他数据库或其他与持久性相关的特定依赖项,超过持久层的边界。 它还为您提供了一个检查所有映射规则的好地方 - 易于测试和更改,并且您可以制作漂亮的上下文特定模型来实现他们的上下文所需的内容,例如这个 Car class 附加单词"horses" 到马力 属性.

我创建了这个小例子来展示这个:

public class CarRepository
{
    private readonly SqlCarStore _carStore;

    public CarRepository(SqlCarStore carStore)
    {
        _carStore = carStore;
    }

    public IEnumerable<Car> GetCars()
    {
        IEnumerable<CarEntity> dbCars = _carStore.GetCars();
        return dbCars.Select(c => c.ToCar());

    }
}
public static class CarEntityExtensions
{
    //Maps from CarEntity to Car
    public static Car ToCar(this CarEntity entityCar)
    {
        return new Car
        {
            Make = entityCar.Make,
            Model = entityCar.Model,
            Year = entityCar.Year,
            HorsePower = entityCar.HorsePower.ToString(),

        };
    }
}
public class CarEntity
{
    public string Id { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public string Year { get; set; }
    public int HorsePower { get; set; }
}

public class Car
{
    private string _horsePower;
    public string Make { get; set; }
    public string Model { get; set; }
    public string Year { get; set; }

    public string HorsePower
    {
        get { return _horsePower; }
        set { _horsePower = $"{value} horses"; }
    }
}

另一个以 Linq 为中心的解决方案,如果你做了很多 CarEntityCar 的映射,将创建一个隐式转换并使用 Cast<>:

public static implicit operator Car(CarEntity aCE) {
    return new Car() { CarId = aCE.Id, CarColor = aCE.Color,
        CarMake = aCE.Make, CarModel = aCE.Model };
}

然后你就可以

List<Car> cars = carEntities.Cast<Car>();