gpt4 book ai didi

c# - 希望将实体作为通用类型传递并提取通用功能

转载 作者:行者123 更新时间:2023-12-05 09:36:59 24 4
gpt4 key购买 nike

我有一个如下所示的实体结构,我在这里所做的是基于输入查找主实体,然后通过导航属性查找子实体,然后从不同位置的子表中删除子实体

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

下面是删除子实体的代码

方法一:

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

我正在寻找一种通用方法,我们可以将实体作为通用类型传递并进行删除,有人可以告诉我如何实现吗?

提前致谢!!

最佳答案

and then through navigation property finding the child entity

您不需要手动执行此操作,EF Core 可以使用 Loading Related Data 的可用方法为您执行此操作- 渴望,明确或懒惰。在这种特殊情况下,预加载可能是最合适的,因为它允许您将前两个步骤(查找主实体和关联的子实体)合并为一个数据库请求。

无论您选择哪种查找子实体的方法,所讨论方法的概括都是提供导航属性访问器表达式 (Expression<Func<TParent, TChild>>),这足以执行与当前代码等效的操作。

例如,假设 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);
}
}

但现在可以很容易地看出您并不真正需要父实体,因此实现可以简化(并且也变得更高效)如下(相同的方法签名):

var child = db.Set<TParent>()
.Where(p => p.Id == parentId)
.Select(childReference) // <--
.FirstOrDefault();
if (child != null)
db.Remove(child);

在这两种情况下,这 3 个调用都是

if (requestInput.RequestType == RequestAction.EDIT)
RemoveChild(dbContext, requestInput.DataId, (GlazingOrGasMaterial m) => m.{NavigationProperty});

哪里m.{NavigationProperty}分别是m.GlazingGasMaterial , m.GlazingComplexMaterialm.GlazingSimpleMaterial

关于c# - 希望将实体作为通用类型传递并提取通用功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64637267/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com