Ну, поскольку ответа пока нет, я сам напишу.
Для тех, кому интересно, я получил его на работу - код выглядит ужасно чертовски, и я думаю, что производительность еще хуже.Но так как пользователей будет не так много, и этот метод будет вызываться только один раз в день ночью, мне все равно сейчас это хорошо.
Что я сделал?
Ну, я пошел сВарианты 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 нет механизма, который говорит: «Эй, подожди минутку - это одно и то же!»В моем примере я добавил «first», чтобы предположить, что всякий раз, когда я использую «first», на него ссылаются.(Я действительно надеюсь, что мой пример работает так, как описано - у меня нет ни времени, ни желания его протестировать)