gpt4 book ai didi

c# - Entity Framework - 更新没有 Id 的实体

转载 作者:太空宇宙 更新时间:2023-11-03 14:29:23 28 4
gpt4 key购买 nike

我在 SO 和互联网上的文章中发现了很多问题,但没有一个真正解决了我的问题。

我的模型看起来像这样(我去掉了所有非必要的属性): alt text

每天左右“播放”都会更新(通过包含信息的 XML 文件)。

internal Play ParsePlayInfo(XDocument doc)
{
Play play = (from p in doc.Descendants("Play")
select new Play
{
Theatre = new Theatre()
{
//Properties
},
//Properties
LastUpdate = DateTime.Now
}).SingleOrDefault();

var actors = (from a in doc.XPathSelectElement(".//Play//Actors").Nodes()
select new Lecturer()
{
//Properties
});

var parts = (from p in doc.XPathSelectElement(".//Play//Parts").Nodes()
select new Part()
{
//Properties
}).ToList();

foreach (var item in parts)
{
play.Parts.Add(item);
}

var reviews = (from r in doc.XPathSelectElement(".//Play//Reviews").Nodes()
select new Review
{
//Properties
}).ToList();

for (int i = 0; i < reviews.Count(); i++)
{
PlayReviews pR = new PlayReviews()
{
Review = reviews[i],
Play = play,
//Properties
};
play.PlayReviews.Add(pR);
}
return play;
}

如果我通过 Add() 添加这个“play”,Play 的每个 Childobject 都将被插入——不管是否已经存在。由于我需要更新现有条目,因此我必须为此做些事情。我想这里的问题是我在 XML 中没有任何 ID。

据我所知,我有以下选择:

  1. 添加/更新我的子实体PlayRepositories 添加方法
  2. 重组和重写ParsePlayInfo() 以便获得所有子实体优先,添加或更新他们然后然后创建一个新的 Play。我这里唯一的问题是我希望 ParsePlayInfo() 成为坚持无知,我可以工作围绕这个
  3. 创造多个解析方法(例如 ParseActors() )并分配他们在我的 Controller (我正在使用 ASP.net MVC)在解析并添加所有内容之后

目前我正在实现选项 1 - 但感觉不对。

我想做的是更新数据库中已有的实体并插入不存在的新实体。在附加/添加播放之前我必须调用 SaveChanges() 吗?必须有一个(相对)简单的解决方案。如果有人能在这方面指导我正确的方向,我将不胜感激。

最佳答案

好吧,既然还没有答案,我自己写一个。

对于那些想知道的人,我让它工作了 - 代码看起来很难看,我猜性能更差。但是因为不会有很多用户,而且这个方法只会在一天晚上调用一次,所以我暂时可以接受。

我做了什么?

好吧,我选择了选项 2 和 3。

private Play UpdatePlay()
{
using (RepositoryContext context = new RepositoryContext())
{
HttpRequest http = new HttpRequest();
PlayRepository rep = new PlayRepository(context);

ActorRepository actRep = new ActorRepository(context);
ReviewsRepository revRep = new ReviewsRepository(context);
TheatreRepository insRep = new TheatreRepository(context);
PartRepository partRep = new PartRepository(context);

Parser p = new Parser();

XDocument doc = http.GetPlayInfo();

Theatre theatre = p.ParseTheatreInfo(doc);
List<Actor> actors = p.ParseActorInfo(doc);
List<PlayReviews> playReviews = p.ParseReviewsInfo(doc);

for (int i = 0; i < actors.Count; i++)
{
actors[i] = actRep.AddOrUpdate(actors[i]);
}
for (int i = 0; i < playReviews.Count; i++)
{
playReviews[i].Reviews = revRep.AddOrUpdate(playReviews[i].Reviews);
}

theatre = insRep.AddOrUpdate(theatre);

Play play = p.ParsePlayInfo(doc);

List<Part> parts = GetParts(play);

for (int i = 0; i < parts.Count; i++)
{
List<Actor> lec = (List<Actor>)parts[i].Actors;
for (int j = 0; j < lec.Count; j++)
{
lec[j] = actRep.AddOrUpdate(lec[j]);
}

}

play = rep.AddOrUpdate(play);
context.LoadProperty(play, o => o.Theatre);
context.LoadProperty(play, o => o.Actors);
context.LoadProperty(play, o => o.PlayReviewss);
context.LoadProperty(play, o => o.Parts);

rep.Save();

if (play.Theatre != theatre)
play.Theatre = theatre;

play = rep.AddParts(parts, play);

play = rep.AddActor(actors, play);

for (int i = 0; i < playReviews.Count; i++)
{
playReviews[i].Play = play;
playReviews[i] = revRep.AddPlayInformation(playReviews[i]);
}

rep.Save();
return play;
}
}

(顺便说一句,我刚刚意识到我之前忘记发布我的这部分代码...)

如您所见,Save() 被调用了两次 - 当您考虑 AddOrUpdate() 中发生的事情时,情况会变得更糟:

public Actor AddOrUpdate(Actor entity)
{
Actor cur = context.Actors.Where(l => l.Name == entity.Name && l.Last_Name == entity.Last_Name).FirstOrDefault();
if (cur == null)
{
context.Actors.AddObject(entity);
return entity;
}
else
{
if (!entity.Mail.IsNullOrEmptyOrWhitespace() && cur.Mail != entity.Mail)
cur.Mail = entity.Mail;
//there are more of these...

return cur;
}
}

我无法相信这是执行此操作的“正确”方法。感觉和看起来都是错误的。也许 EF 也有责任,拿

FirstEntityType first = new FirstEntityType();
first.Id = 2;
List<SecondType> list = CreateList(); //Let's say this returns a List with 10 elements
context.FirstEntityType.AddObject(first);

for (int i = 0; i < list.Count; i++)
{
list[i].First = first;
}

//just for arguments sake a second for
for (int i = 0; i < list.Count; i++)
{
context.SecondType.AddObject(list);
}

context.SaveChanges();

我没有测试过这段特定的代码,但根据我的经验,我最终会得到 10 个用于 SecondType 的新条目,如果我没记错的话,11 个用于 FirstEntityType。

为什么?为什么 EF 中没有一种机制说“嘿,等一下 - 它们是一样的!”

如果我直接使用数据库,我是否认为 EF 的行为应该是错误的?在我的示例中,我添加了“first”,这样我就可以假设每当我使用“first”时都会引用它。(我真的希望我的例子能像描述的那样工作——没有时间也不想测试它)

关于c# - Entity Framework - 更新没有 Id 的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3000817/

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