我有一个列表,其中包含自参考项。
例如:
型号
public class Stock{
public int StockId { get; set; }
public int? ParentStockId { get; set; }
public int Level { get; set; }
public string Name { get; set; }
}
ViewModel
public class StockViewModel {
public int Level { get; set; }
public string Name { get; set; }
public IEnumerable<StockViewModel> SubStock { get; set; }
}
样本数据
var stocks = new List<Stock> {
new Stock{ StockId = 1, Level = 10, Name = "Root1" },
new Stock{ StockId = 2, Level = 10, Name = "Root2" },
new Stock{ StockId = 3, ParentStockId = 1, Level = 20, Name = "Area1" },
new Stock{ StockId = 4, ParentStockId = 2, Level = 20, Name = "Area2" },
new Stock{ StockId = 5, ParentStockId = 3, Level = 30, Name = "Box11" },
new Stock{ StockId = 6, ParentStockId = 3, Level = 30, Name = "Box12" },
new Stock{ StockId = 7, ParentStockId = 4, Level = 30, Name = "Box21" }
};
我使用类似的代码来实现所需的结果。但我确定这是错误的。我必须在每个新请求之前进行配置。
var mapper = new Mapper();
TypeAdapterConfig<Stock, StockViewModel>
.NewConfig()
.Map(dst => dst.SubStock, src => stocks.Where(x => x.ParentStockId == src.StockId).ToList());
var viewStocks = mapper.Map<IEnumerable<Stock>, IEnumerable<StockViewModel>>(stocks.Where(x => x.ParentStockId == null));
// Sample output
foreach (var stock in viewStocks){
Console.WriteLine(stock.Level.ToString() + " " + stock.Name);
if (stock.SubStock != null)
foreach (var stock1 in stock.SubStock){
Console.WriteLine(" " + stock1.Level.ToString() + " " + stock1.Name);
if (stock1.SubStock != null)
foreach (var stock2 in stock1.SubStock){
Console.WriteLine(" " + stock2.Level.ToString() + " " + stock2.Name);
}
}
}
Fiddle
如何映射viewStocks
层级?
与
10 Root1
20 Area1
30 Box11
30 Box12
10 Root2
20 Area2
30 Box21
答案 0 :(得分:1)
您无需为每个新请求配置Mapster
配置。根据{{3}}:
配置应仅设置一次,并重新用于映射。 因此,我们不应将配置和映射保留在同一位置 位置。配置应保留在诸如
Main
函数或Global.asax.cs
或Startup.cs
之类的入口点。
因此您可以将该映射移至入口点:
TypeAdapterConfig<Stock, StockViewModel>
.NewConfig()
.Map(dst => dst.SubStock, src => stocks.Where(x => x.ParentStockId == src.StockId).ToList());
此外,为了分隔您的配置和映射实例而不是
var viewStocks = mapper.Map<IEnumerable<Stock>, IEnumerable<StockViewModel>>(stocks.Where(x => x.ParentStockId == null));
我更喜欢按以下方式使用Adapt
:
var socksWithoutParent = stocks.Where(x => x.ParentStockId == null);
var viewStocks = socksWithoutParent.Adapt<List<StockViewModel>>();
完整示例https://github.com/MapsterMapper/Mapster/wiki/Config-location,它将为您提供相同的输出:
10 Root1
20 Area1
30 Box11
30 Box12
10 Root2
20 Area2
30 Box21
答案 1 :(得分:0)
为了正确地分离配置和映射,我用stocks
传递参数
var viewStocks = stocks.Where(x => x.ParentStockId == null)
.BuildAdapter()
.AddParameters("paramKey", stocks)
.AdaptToType<List<StockViewModel>>();
和我的配置
TypeAdapterConfig<Stock, StockViewModel>
.NewConfig()
.Map(dst => dst.SubStock,
src => ((IEnumerable<Stock>)MapContext.Current.Parameters["paramKey"])
.Where(x => x.ParentStockId == src.StockId)
.BuildAdapter()
.AddParameters("paramKey", MapContext.Current.Parameters["paramKey"])
.AdaptToType<List<StockViewModel>>());
现在在我的配置中,我不需要了解stocks