gpt4 book ai didi

c# - EF 6.0 多对多插入这么多编码......为什么?

转载 作者:行者123 更新时间:2023-11-30 17:40:20 25 4
gpt4 key购买 nike

我的问题更多是为什么 ef 6.0 不支持忽略重复项?

举个例子:

我有两张 table

  1. 应用程序 { id, AppName }
  2. 广告组 {id,GroupName}

应用程序与 ADGroups 有很多对多的关系。现在,每次我添加带有广告组的应用程序时,我都需要首先执行以下操作以避免重复插入键:

  1. 检查应用程序是否已经存在
  2. 检查指定的广告组是否已经存在
  3. 找出不同点
  4. 更新数据库

这似乎只是为了插入一个血腥的关系而做的很多工作。可以编写一个sql查询来在插入中进行选择,以确保数据不存在,然后执行插入。它将返回 0 或 1,具体取决于该行是否已存在

假设 n 到 n 表将称为 Applications_AdGroup

然后插入关系的查询将是这样的(未测试):

Insert Into Applications (AppName)
select 'CRM'
where NOT EXISTS(
select 1
from Applications
where AppName = 'CRM'
)

Insert Into AdGroup (GroupName)
select 'CRM_ADMIN'
where NOT EXISTS(
select 1
from Applications
where AppName = 'CRM_ADMIN'
)

Insert Into Applications_AdGroup (id_adgroup, id_applications)
select
adgroup.id,
applications.id
from
adgroup,
applications
where
adgroup.GroupName = 'CRM_ADMIN' AND
applications.AppName = 'CRM' AND

WHERE NOT EXISTS (
select 1
from
Applications_Adgroup
where
Applications_AdGroup.id_adgroup = adgroup.id AND
Applications_AdGroup.id_applications = applications.id
)

所以基本上即使应用程序、广告组或关系已经存在,它也不会插入任何内容...

一天结束时,将对 db.Applications.Add (obj) 进行简单调用,然后保存更改。所有检查都在后台进行,一切正常吗?

对此有何看法?我只是做错了吗?

编辑我想用 ef 方式会出现一些并发问题。在上述 4 个步骤中的任何一个过程中,另一个进程可能会插入 AdGroup,无论如何您都会遇到重复键错误

编辑附上映射:

//Relation between Application and the Parent Group
modelBuilder.Entity<Applications>()
.HasMany<AdGroup>(s => s.Groups)
.WithMany(a => a.Applications)
.Map(cs =>
{
cs.MapLeftKey("Application");
cs.MapRightKey("AdGroup");
cs.ToTable("Application_Groups");
});

编辑下面是我用来插入关系的代码示例:

使用 (var db = new ARContext()){

var val = new Applications
{
Application = "CRM",
Groups = new List<AdGroup> {
new AdGroup { Group = "CRM_ADMIN" },
new AdGroup { Group = "CRM_Boutique1" },
new AdGroup { Group = "CRM_Boutique2" },
}
};

var dbArr = db.Applications.Where(a => a.Application == val.Application).FirstOrDefault();

if (dbArr == null)
{
db.Applications.Add(new Applications() { Application = val.Application });
db.SaveChanges();
}

dbArr = db.Applications.Where(a => a.Application == val.Application).FirstOrDefault();

if (dbArr.Groups == null)
{
dbArr.Groups = new List<AdGroup>();
}

foreach (var gr in val.Groups)
{
var dbGrp = db.Groups.Where(g => g.Group == gr.Group).FirstOrDefault();

if (dbGrp == null)
{
dbArr.Groups.Add(gr);
}
else
{
dbArr.Groups.Add(dbGrp);
}
}

db.SaveChanges();

上面使用的名称和代码示例存在一些差异,但要点就在那里......

因此,首先我需要保存新应用程序,然后处理各个组以查看它们是否存在并相应地添加到上下文中。这是除了编写存储过程之外的唯一方法吗??

谢谢

最佳答案

像这样的东西也应该可以解决问题:

using(var db = new ARContext())
{
var groupNames = new[] {"CRM_ADMIN","CRM_Boutique1","CRM_Boutique2"};

//Fetch application (AdGroups eager loaded) if it exists, otherwise create a new one
var application = db.Applications.Include(a => a.AdGroups)
.FirstOrDefault(a => a.Application == "CRM")
?? db.Add(new Application { Application = "CRM" });

//If the application didn't exist yet, initialize the AdGroup collection
//Better to do this in the constructor of your application model though
if(db.Entry(application).State == EntityState.Added)
application.AdGroups = new List<AdGroup>();

//Iterate over groupNames that are not part of application.Adgroup's collection
foreach(var name in groupNames.Where(g => !application.AdGroups.Any(ag => ag.GroupName == g)))
{
AdGroup group = db.AdGroups.FirstOrDefault(ag => ag.GroupName == name)
?? db.Add(new AdGroup { GroupName = name });
application.AdGroups.Add(group);
}

db.SaveChanges();
}

您的示例有点不寻常,因为您对 ApplicationAdGroup 或它们之间的关系一无所知,这会导致代码中出现大量检查。首先,如果应用程序存在(包括 AdGroups 通过 Eager Loading),我会从数据库中获取应用程序,否则我将创建一个新应用程序。如果我必须创建一个新的,则应该初始化 AdGroup 集合(除非您在模型的构造函数中这样做)。最后,遍历不在集合 Application.AdGroups 中的组名。如果该组存在,则获取它,如果不存在,则创建它并将它们添加到 Application.AdGroups

关于c# - EF 6.0 多对多插入这么多编码......为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34412661/

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