.Net Entity Framework SaveChanges добавляется без метода добавления

Я новичок в инфраструктуре сущностей, и я действительно не понимаю, как работает savechanges. Вероятно, в моем примере много кода, который можно было бы улучшить, но вот проблема, с которой я столкнулся.

Пользователь вводит кучу вариантов. Я удостоверяюсь, что пользователь еще не ввел эти выборы. Затем я добавляю выборки в базу данных.

       var db = new myModel()
       var predictionArray = ticker.Substring(1).Split(','); // Get rid of the initial comma.

        var user = Membership.GetUser();
        var userId = Convert.ToInt32(user.ProviderUserKey);

        // Get the member with all his predictions for today.
        var memberQuery = (from member in db.Members
                         where member.user_id == userId
                         select new
                                    {
                                        member,
                                        predictions = from p in member.Predictions
                                                     where p.start_date == null
                                                     select p

                                    }).First();

        // Load all the company ids.
        foreach (var prediction in memberQuery.predictions)
        {
            prediction.CompanyReference.Load();
        }

 var picks = from prediction in predictionArray
                          let data = prediction.Split(':')
                          let companyTicker = data[0]
                          where !(from i in memberQuery.predictions
                                 select i.Company.ticker).Contains(companyTicker)
                          select new Prediction
                          {
                              Member = memberQuery.member,
                              Company = db.Companies.Where(c => c.ticker == companyTicker).First(),
                              is_up = data[1] == "up",  // This turns up and down into true and false.
                          };


    // Save the records to the database.
    // HERE'S THE PART I DON'T UNDERSTAND.
    // This saves the records, even though I don't have db.AddToPredictions(pick) 
            foreach (var pick in picks)
            {
                    db.SaveChanges();
            }

// This does not save records when the db.SaveChanges outside of a loop of picks.
 db.SaveChanges();
 foreach (var pick in picks)
            {

            }

// This saves records,  but it will insert all the picks exactly once no matter how many picks you have.  
//The fact you're skipping a pick makes no difference in what gets inserted.
            var counter = 1;
            foreach (var pick in picks)
            {
                if (counter == 2)
                {
                    db.SaveChanges();
                }
                counter++;
            }

Я тестировал, и SaveChanges даже не обязательно должен быть в цикле. Приведенный ниже код тоже работает.

foreach (var pick in picks)
            {
                   break;
            }

db.SaveChanges()

Очевидно, что-то происходит с контекстом, которого я не понимаю. Я предполагаю, что каким-то образом загрузил свои новые выборки как ожидающие изменения, но даже если это правда, я не понимаю, что мне нужно перебрать их, чтобы сохранить изменения.

Может кто-то объяснить это мне?

Вот обновленный рабочий код, основанный на ответах Крейга: 1) Удалите тип, затем выполните цикл по результатам и заполните новые объекты.

var  picks = (from prediction in predictionArray
                        let data = prediction.Split(':')
                        let companyTicker = data[0]
                        where !(from i in memberQuery.predictions
                                select i.Company.ticker).Contains(companyTicker)
                        select new //NO TYPE HERE
                        {
                            Member = memberQuery.member,
                            Company = db.Companies.Where(c => c.ticker == companyTicker).First(),
                            is_up = data[1] == "up",  // This turns up and down into true and false.
                        }).ToList();

            foreach (var prediction in picks)
            {
              if (includePrediction)
               {
                var p = new Prediction{
                  Member = prediction.Member,
                  Company = prediction.Company,
                  is_up = prediction.is_up
                 };
                db.AddToPredictions(p);
                }
            }

2) Или, если я не хочу, чтобы прогнозы сохранялись, я могу отделить прогнозы.

foreach (var prediction in picks) {
                  if  (excludePrediction)
                  {
                      db.Detach(prediction)
                   }

}

person notorange    schedule 12.03.2010    source источник


Ответы (1)


Причина здесь:

                      select new Prediction
                      {
                          Member = memberQuery.member,

Эти строки будут (после повторения IEnumerable; LINQ ленив):

  1. Создать новый Prediction
  2. Свяжите этот Prediction с существующим Member, *который присоединен к db.

Связывание экземпляра объекта с присоединенным объектом автоматически добавляет этот объект в контекст связанного присоединенного объекта.

Итак, как только вы начинаете перебирать predictionArray, код выше выполняется, и у вас есть новый объект в вашем контексте.

person Craig Stuntz    schedule 12.03.2010
comment
Кажется, я начинаю понимать это. Как мне отделить прогнозы, если я хочу? Я также нашел это (для всех, кто читает это), которое объясняет отложенное выполнение, о котором вы упомянули, что помогло мне понять, почему мне нужно было вызвать переменную выбора перед сохранением. Я заменил цикл командой ToList(). codewrecks.com/blog/index .php/2009/01/08/ - person notorange; 12.03.2010
comment
Вы отсоединяетесь с помощью Context.Detach. Но вы также можете просто проецировать на анонимный тип (или другой POCO) вместо нового экземпляра объекта. - person Craig Stuntz; 12.03.2010
comment
Спасибо, Крейг. Я обновил свой вопрос на основе ваших ответов. Это было большим подспорьем. - person notorange; 12.03.2010