我在这里找到了很多关于SO和文章的问题,但没有一个问题真正解决了我的问题。
我的模型看起来像这样(我镶边了所有非必要的属性): alt text http://i47.tinypic.com/244p6qh.jpg
每天都会“更新”“播放”(通过包含信息的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”,则会插入每个Childobject of Play - 无论是否已存在某些。由于我需要更新现有条目,我必须对此做些什么。我想这里的问题是我在XML中没有Id。
据我所知,我有以下选择:
目前我正在实施选项1 - 但感觉不对。
我想要做的是更新数据库中已有的实体并插入不存在的新实体。 在附加/添加播放之前,是否必须调用SaveChanges()?必须有(相对)简单的解决方案。 如果有人能指导我在这个方向上朝着正确的方向前进,我会很感激。
答案 0 :(得分:1)
好吧,既然没有答案,我会自己写一个。
对于那些想知道的人,我让它发挥作用 - 代码看起来很丑陋,我想性能更糟。但是因为不会有很多用户,而且这种方法每天只会被调用一次,所以我现在很好用。
我做了什么?
好吧,我选择了选项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();
我没有测试过这段特殊的代码,但从我的经验来看,我最终将为SecondType添加10个新条目,如果我对FirstEntityType没有错误11。
为什么呢?为什么EF中没有一种机制可以说“嘿,等一下 - 这些都是一样的!”
如果我直接使用数据库,EF应该表现得如此错误吗?在我的例子中,我添加了“first”,所以我可以假设每当我使用“first”时它都被引用。 (我真的希望我的例子按照描述的方式工作 - 没有时间也没有测试它的愿望)