2

我是实体框架的新手,我对 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()

显然,我不明白的上下文发生了一些事情。我猜我已经以某种方式将我的新选择加载为待处理的更改,但即使这是真的,我也不明白我必须遍历它们以保存更改。

谁可以给我解释一下这个?

以下是根据 Craig 的回复更新的工作代码: 1) 删除 Type 然后循环遍历结果并填充新对象。

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)
                   }

}
4

1 回答 1

3

原因在这里:

                      select new Prediction
                      {
                          Member = memberQuery.member,

这些行将(一旦IEnumerable被迭代;LINQ 是惰性的):

  1. 实例化一个新的Prediction
  2. 将其与附加到Prediction的现有* 关联。Memberdb

将实体的实例与附加实体关联会自动将该实体添加到关联的附加实体的上下文中。

因此,一旦您开始迭代predictionArray,上面的代码就会执行,并且您的上下文中有一个新实体。

于 2010-03-12T14:15:11.937 回答