【发布时间】:2021-07-29 06:56:27
【问题描述】:
我有一个下面的方法,我循环遍历 id 列表并根据 id 从 db 获取数据,然后创建材料,然后添加到材料列表中
public Construction AddToOsm(Model model, APIDbContext dbContext)
{
var construction = new Construction(model);
var surfaceType = dbContext.IntendedSurfaceTypes.SingleOrDefault(s => s.Id == this.SurfaceTypeId);
construction.setName(surfaceType?.Name);
using var materials = new MaterialVector();
var fenestrationMaterialById = new Dictionary<Guid, FenestrationMaterial>();
var opaqueMaterialById = new Dictionary<Guid, StandardOpaqueMaterial>();
foreach (var materialId in this.LayerIds.Where(i => i != default))
{
var opaqueMaterial = dbContext.OpaqueMaterials.SingleOrDefault(o => o.Id == materialId);
if (opaqueMaterial != default)
{
materials.Add(opaqueMaterialById.GetOrCreate(opaqueMaterial.Id, () => opaqueMaterial.AddToOsm(model)));
}
else
{
var glazingMaterial = dbContext.GlazingMaterials.SingleOrDefault(o => o.Id == materialId);
if (glazingMaterial != default)
{
materials.Add(fenestrationMaterialById.GetOrCreate(glazingMaterial.Id, () => glazingMaterial.AddToOsm(model)));
}
else
{
var glazingSimpleMaterial = dbContext.SimpleGlazingMaterials.SingleOrDefault(s => s.Id == materialId);
if(glazingSimpleMaterial != default)
{
materials.Add(fenestrationMaterialById.GetOrCreate(glazingSimpleMaterial.Id, () => glazingSimpleMaterial.AddToOsm(model)));
}
else
{
var gasGlazingMaterials = dbContext.GasGlazingMaterials.SingleOrDefault(a => a.Id == materialId);
if(gasGlazingMaterials != default)
{
materials.Add(fenestrationMaterialById.GetOrCreate(gasGlazingMaterials.Id, () => gasGlazingMaterials.AddToOsm(model)));
}
}
}
}
}
construction.setLayers(materials);
return construction;
}
我正在寻找一种方法来避免这么多 if-else 语句,主要是重构它,但找不到办法。任何人都可以就如何实现这一目标提出任何想法。
提前致谢。
更新:示例实体结构
public class GasGlazingMaterial : ISourceOfData, IIdentity<Guid>
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
[ForeignKey("SourceOfData")]
public Guid? SourceOfDataId { get; set; }
public virtual CodeStandardGuideline SourceOfData { get; set; }
......
.....
}
【问题讨论】:
-
通常,我使用循环来解决重复的
if函数。如果您制作一个对象列表并遍历它们会怎样?然后为每一个检查if object = default: exit. else: continue。 -
是的,问题是如果
object = default,那么如果第一个对象不可用,我需要检查其他对象 -
这看起来是在测试材料“类型”,这让我认为数据结构实际上是导致问题的原因。我想知道返回并查看数据库结构是否是一个好主意。同样令人担忧的是,这段代码正在多个表中测试相同的“ID”,我认为这是另一个危险信号。
-
实际结构是这样的
public class SurfaceConstruction : IIdentity<Guid> { [Key] public Guid Id { get; set; } public Guid SurfaceTypeId { get; set; } public IntendedSurfaceType SurfaceType { get; set; } public List<Guid> LayerIds { get; set; } public Construction AddToOsm(Model model, APIDbContext dbContext) { ..... -
循环遍历
LayerIds并找到相应的材料然后添加到材料中,所有材料实体(OpaqueMaterials...)都来自IIdentity<Guid>
标签: c# .net linq .net-core refactoring