将IEnumerable转换为另一个IEnumerableC#

本文关键字:另一个 IEnumerableC# 转换 IEnumerable | 更新日期: 2023-09-27 18:14:47

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

我需要将IEnumerable<Car>的对象从我的服务返回到我的控制器。我的服务调用我的存储库,该存储库返回IEnumerable<CarEntity>

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

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列表?我认为还有更精明的方法可以做到这一点。

将IEnumerable转换为另一个IEnumerableC#

是。您需要为汽车实体列表集合中的每个项目创建一个新的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。在IEnumerable<T>上选择扩展方法以将项目从一个集合扩展到另一个集合:

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

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

如果您执行大量CarEntityCar映射,另一个以Linq为中心的解决方案将是创建隐式转换并使用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>();

假设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

它实际上很简单让我们假设您的收藏如下

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);
}

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

这是为了不将对实体的依赖关系以及可能的其他数据库或与持久性相关的其他特定依赖关系放在持久性层的边界之外。此外,它还为您提供了一个检查所有映射规则的好地方-易于测试和更改,并且您可以创建良好的上下文特定模型,实现上下文所需的内容,比如在马力属性中添加单词"horses"的Car类。

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

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"; }
    }
}