C# 将IEnumerable转换为另一IEnumerable C

C# 将IEnumerable转换为另一IEnumerable C,c#,asp.net-mvc,linq,linq-to-entities,C#,Asp.net Mvc,Linq,Linq To Entities,来自JS/PHP/Node背景,对C应用程序开发人员来说有些陌生。正在开发MVC应用程序 我需要将IEnumerable对象从我的服务返回给我的控制器。我的服务调用我的存储库,它返回IEnumberable 我想不出如何将一份小心清单转换成一份汽车清单 这辆车看起来像 public int CarId { get; set; } public string CarColor { get; set; } public string CarMake { get; set; }

来自JS/PHP/Node背景,对C应用程序开发人员来说有些陌生。正在开发MVC应用程序

我需要将IEnumerable对象从我的服务返回给我的控制器。我的服务调用我的存储库,它返回IEnumberable

我想不出如何将一份小心清单转换成一份汽车清单

这辆车看起来像

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

这是一个例子,但这通常是我需要的。我是否需要在我的关注列表中做一些循环,并将每个列表推到汽车列表中?我想还有更精明的方法

是的。您需要为“汽车实体列表”集合中的每个项目创建一个新的汽车对象,并指定特性值。您可以在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的扩展方法,将一个集合中的项扩展到另一个集合中:

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

IEnumerable<Car> cars = 
    carEntities
    .Select(c => 
         new Car
         {
             CarId = c.Id,
             CarColor = c.Color,
             //etc.
         });
有这样的工具,但我没有使用它们的经验。

假设结果是可数的:


结果将是您的IEnumerable

它实际上非常简单 让我们假设您的集合如下

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

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

这是为了不将对实体的依赖关系以及可能的其他数据库或与持久性相关的其他特定依赖关系置于持久性层的边界之外。 此外,它还为您提供了一个检查所有映射规则的好地方—易于测试和更改,并且您可以创建良好的特定于上下文的模型,这些模型实现了上下文所需的内容,例如在horsepower属性后面添加单词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"; }
    }
}

另一个以Linq为中心的解决方案是创建一个隐式转换并使用Cast,如果您对汽车进行了大量细致的映射:

然后你就可以

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

顺便说一句,如果你经常需要从CarEntities制造汽车,一个接受CarEntity的汽车的构造器可以大大简化事情,而且出错的可能性也更小。谢谢你把这两种方法都放在这里,我应该提到我正在使用LINQ。使用LINQ,如果输入和输出恰好具有相同的确切属性,我是否能够设置carList=carEntityList,还是仍然需要转换?如果我必须转换,当属性的类型和名称相同时,是否有快捷方式?只是好奇。谢谢,您不能这样做,因为两者都是不同类型的集合。您将得到一个编译时错误,说明collectionX无法转换为collectionY!。所以你需要做这个创建对象集属性值的事情。如果您使用的是LINQ,只需使用Select扩展方法,正如我在答案的第二部分中所示。这几乎是一个元问题:您对在代码末尾使用ToList回答这个问题有什么想法?一方面,用户可能是无知的,因此更安全的做法是始终将ToList放在这行代码上,而不是放在最后使用结果的那行代码上,另一方面,我们可能应该假设他们知道LINQ是如何工作的。Select已经有5个答案,其中一个决定使用ToList,但其他人都没有。迂腐的,或者重要的是要向提问者指出?显然,这里的许多编辑不知道C或Linq是如何工作的。您的答案有一个输入错误,其中设置了CarEntity ID、颜色、品牌、型号以及尝试创建新车时的字段。他们应该是CarID,CarColor,CarMake和CarModel当制造一辆汽车。或者你的汽车实体可以继承carI你认为你的意思是IEnumerable?由于Stack不允许第三方轻松编辑打字错误。。。
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);
}
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"; }
    }
}
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>();