C# 希望将实体作为泛型类型传递并提取通用功能
我有一个如下所示的实体结构,我在这里所做的是基于输入查找主实体,然后通过导航属性查找子实体,然后从不同位置的子表中删除子实体C# 希望将实体作为泛型类型传递并提取通用功能,c#,.net,linq,generics,entity-framework-core,C#,.net,Linq,Generics,Entity Framework Core,我有一个如下所示的实体结构,我在这里所做的是基于输入查找主实体,然后通过导航属性查找子实体,然后从不同位置的子表中删除子实体 public class GlazingOrGasMaterial : AEIMasterBase { [ForeignKey("SourceOfData"), GraphQLIgnore] public Guid? SourceOfDataId { get; set; } public virtual CodeStandard
public class GlazingOrGasMaterial : AEIMasterBase
{
[ForeignKey("SourceOfData"), GraphQLIgnore]
public Guid? SourceOfDataId { get; set; }
public virtual CodeStandardGuideline SourceOfData { get; set; }
[ForeignKey("GlazingComplexMaterial"), GraphQLIgnore]
public Guid? GlazingComplexMaterialId { get; set; }
[ForeignKey("GlazingSimpleMaterial"), GraphQLIgnore]
public Guid? GlazingSimpleMaterialId { get; set; }
[ForeignKey("GlazingGasMaterial"), GraphQLIgnore]
public Guid? GlazingGasMaterialId { get; set; }
public virtual GlazingComplexMaterial GlazingComplexMaterial { get; set; }
public virtual GlazingSimpleMaterial GlazingSimpleMaterial { get; set; }
public virtual GlazingGasMaterial GlazingGasMaterial { get; set; }
}
下面是删除该子实体的代码
方法1:
if(requestInput.RequestType == RequestAction.EDIT)
{
var existingGlazingOrGasMaterial = dbContext.GlazingOrGasMaterials.Find(requestInput.DataId);
if(existingGlazingOrGasMaterial != default)
{
var existingGasMaterial = dbContext.GlazingGasMaterials.SingleOrDefault(gasMaterial => gasMaterial.Id == existingGlazingOrGasMaterial.GlazingGasMaterialId);
if(existingGasMaterial != default)
{
dbContext.GlazingGasMaterials.Remove(existingGasMaterial);
}
}
}
if (requestInput.RequestType == RequestAction.EDIT)
{
var existingGlazingOrGasMaterial = dbContext.GlazingOrGasMaterials.Find(requestInput.DataId);
if (existingGlazingOrGasMaterial != default)
{
var existingComplexMaterial = dbContext.GlazingComplexMaterials.SingleOrDefault(complexMaterial => complexMaterial.Id == existingGlazingOrGasMaterial.GlazingComplexMaterialId);
if (existingComplexMaterial != default)
{
dbContext.GlazingComplexMaterials.Remove(existingComplexMaterial);
}
}
}
if (requestInput.RequestType == RequestAction.EDIT)
{
var existingGlazingOrGasMaterial = dbContext.GlazingOrGasMaterials.Find(requestInput.DataId);
if (existingGlazingOrGasMaterial != default)
{
var existingSimpleMaterial = dbContext.GlazingSimpleMaterials.SingleOrDefault(simpleMaterial => simpleMaterial.Id == existingGlazingOrGasMaterial.GlazingSimpleMaterialId);
if (existingSimpleMaterial != default)
{
dbContext.GlazingSimpleMaterials.Remove(existingSimpleMaterial);
}
}
}
下面是我删除该子实体的代码
方法2:
if(requestInput.RequestType == RequestAction.EDIT)
{
var existingGlazingOrGasMaterial = dbContext.GlazingOrGasMaterials.Find(requestInput.DataId);
if(existingGlazingOrGasMaterial != default)
{
var existingGasMaterial = dbContext.GlazingGasMaterials.SingleOrDefault(gasMaterial => gasMaterial.Id == existingGlazingOrGasMaterial.GlazingGasMaterialId);
if(existingGasMaterial != default)
{
dbContext.GlazingGasMaterials.Remove(existingGasMaterial);
}
}
}
if (requestInput.RequestType == RequestAction.EDIT)
{
var existingGlazingOrGasMaterial = dbContext.GlazingOrGasMaterials.Find(requestInput.DataId);
if (existingGlazingOrGasMaterial != default)
{
var existingComplexMaterial = dbContext.GlazingComplexMaterials.SingleOrDefault(complexMaterial => complexMaterial.Id == existingGlazingOrGasMaterial.GlazingComplexMaterialId);
if (existingComplexMaterial != default)
{
dbContext.GlazingComplexMaterials.Remove(existingComplexMaterial);
}
}
}
if (requestInput.RequestType == RequestAction.EDIT)
{
var existingGlazingOrGasMaterial = dbContext.GlazingOrGasMaterials.Find(requestInput.DataId);
if (existingGlazingOrGasMaterial != default)
{
var existingSimpleMaterial = dbContext.GlazingSimpleMaterials.SingleOrDefault(simpleMaterial => simpleMaterial.Id == existingGlazingOrGasMaterial.GlazingSimpleMaterialId);
if (existingSimpleMaterial != default)
{
dbContext.GlazingSimpleMaterials.Remove(existingSimpleMaterial);
}
}
}
方法3:
if(requestInput.RequestType == RequestAction.EDIT)
{
var existingGlazingOrGasMaterial = dbContext.GlazingOrGasMaterials.Find(requestInput.DataId);
if(existingGlazingOrGasMaterial != default)
{
var existingGasMaterial = dbContext.GlazingGasMaterials.SingleOrDefault(gasMaterial => gasMaterial.Id == existingGlazingOrGasMaterial.GlazingGasMaterialId);
if(existingGasMaterial != default)
{
dbContext.GlazingGasMaterials.Remove(existingGasMaterial);
}
}
}
if (requestInput.RequestType == RequestAction.EDIT)
{
var existingGlazingOrGasMaterial = dbContext.GlazingOrGasMaterials.Find(requestInput.DataId);
if (existingGlazingOrGasMaterial != default)
{
var existingComplexMaterial = dbContext.GlazingComplexMaterials.SingleOrDefault(complexMaterial => complexMaterial.Id == existingGlazingOrGasMaterial.GlazingComplexMaterialId);
if (existingComplexMaterial != default)
{
dbContext.GlazingComplexMaterials.Remove(existingComplexMaterial);
}
}
}
if (requestInput.RequestType == RequestAction.EDIT)
{
var existingGlazingOrGasMaterial = dbContext.GlazingOrGasMaterials.Find(requestInput.DataId);
if (existingGlazingOrGasMaterial != default)
{
var existingSimpleMaterial = dbContext.GlazingSimpleMaterials.SingleOrDefault(simpleMaterial => simpleMaterial.Id == existingGlazingOrGasMaterial.GlazingSimpleMaterialId);
if (existingSimpleMaterial != default)
{
dbContext.GlazingSimpleMaterials.Remove(existingSimpleMaterial);
}
}
}
下面是子实体的结构
public class GlazingSimpleMaterial
{
public Guid Id { get; set; }
.....
.....
}
public class GlazingComplexMaterial
{
public Guid Id { get; set; }
.....
.....
}
public class GlazingGasMaterial
{
public Guid Id { get; set; }
.....
.....
}
我正在寻找一种常见的方法,我们可以将实体作为泛型类型传递并进行删除,有人能告诉我如何实现这一点吗
非常感谢 首先,让我们加快查询速度
if (requestInput.RequestType == RequestAction.EDIT)
{
var query =
from m in dbContext.GlazingOrGasMaterials
join gasMaterial in dbContext.GlazingGasMaterials on m.GlazingGasMaterialId equals gasMaterial.Id
where m.Id == requestInput.DataId
select gasMaterial;
var existingGasMaterial = query.FirstOrDefault();
if (existingGasMaterial != default)
{
dbContext.GlazingGasMaterials.Remove(existingGasMaterial);
}
}
如果要盲目删除某些内容,则不需要首先从数据库中加载它
dbContext.GlazingGasMaterials.Remove(
新型玻璃钢材料{
Id=现有GlazingGorgasMaterial.GlazingGasMaterialId
});
假设您的类型实现了一个公共接口来定义它们的主键,那么您可以对上述内容进行概括
publicstaticvoidremove(这个DbContext上下文,Guid Id),其中T:IPrimaryKey,new()=>
dbContext.Set.Remove(
新T{
Id=Id
});
尽管这并没有使代码简化那么多
然后通过导航属性查找子实体
您不需要手动执行此操作,EF Core可以使用可用的方法为您执行此操作-eager、explicit或lazy。在这种特殊情况下,急切加载可能是最合适的,因为它允许您将前两个步骤(查找主实体和关联的子实体)与单个数据库请求结合在一起
无论您选择何种方法来查找子实体,所讨论的方法的泛化将是提供导航属性访问器表达式(expression
),这将足以执行当前代码的等效操作
例如,假设GlazingOrGasMaterial.Id
属性类型为Guid
,并且来自AEIMasterBase
类,则主体可以概括为
public static void RemoveChild<TParent, TChild>(
DbContext db,
Guid parentId,
Expression<Func<TParent, TChild>> childReference // <--
)
where TParent : AEIMasterBase
where TChild : class
{
var parent = db.Set<TParent>()
.Include(childReference) // <--
.FirstOrDefault(p => p.Id == parentId);
if (parent != null)
{
var child = db.Entry(parent)
.Reference(childReference) // <--
.CurrentValue;
if (child != null)
db.Remove(child);
}
}
其中,
m.{NavigationProperty}
分别是m.GlazingAsMaterial
,m.GlazingComplexMaterial
和m.GlazingSimpleMaterial
,GlazingGorgasMaterial
和GlazingComplexMaterial,GlazingSimplexMaterial,GlazingAsMaterial
之间的关系是什么。对于您的型号,我了解到,玻璃钢材质可以有无、一种、两种或三种类型GlazingComplexMaterial、GlazingSimpleMaterial、glazinggasmmaterial
。这是否正确?解决方案将比您的代码更复杂。我认为这是浪费时间。无论如何,试着在一个查询中找到子实体,我看不出发送两个查询的原因。@RodRamírez我确实在每个子实体到父实体之间有一对一的关系entity@SvyatoslavDanyliv你能告诉我正确的方向吗?发一个查询来找到这个孩子entity@IvanStoev,我没有看到有问题的导航属性。我只删除了一个子实体。