.Net Entity Framework SaveChanges 正在添加而无需添加方法

发布于 2024-08-25 15:06:44 字数 4280 浏览 5 评论 0原文

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

}

I'm new to the entity framework and I'm really confused about how savechanges works. There's probably a lot of code in my example which could be improved, but here's the problem I'm having.

The user enters a bunch of picks. I make sure the user hasn't already entered those picks.
Then I add the picks to the database.

       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++;
            }

I've tested and the SaveChanges doesn't even have to be in the loop.
The below code works, too.

foreach (var pick in picks)
            {
                   break;
            }

db.SaveChanges()

There's obviously something going on with the context I don't understand. I'm guessing I've somehow loaded my new picks as pending changes, but even if that's true I don't understand I have to loop over them to save changes.

Can someone explain this to me?

Here's updated working code based on Craig's responses:
1) Remove the Type then loop over the results and populate new objects.

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) Or if I don't want the predictions to be saved, I can detach the predictions.

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦巷 2024-09-01 15:06:44

原因如下:

                      select new Prediction
                      {
                          Member = memberQuery.member,

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

  1. 实例化一个新的 Prediction
  2. 将该 Prediction 与现有成员,*附加到db

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

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

The reason is here:

                      select new Prediction
                      {
                          Member = memberQuery.member,

These lines will (once the IEnumerable is iterated; LINQ is lazy) :

  1. Instantiate a new Prediction
  2. Associate that Prediction with an existing Member, *which is attached to db.

Associating an instance of an entity with an attached entity automatically adds that entity to the context of the associated, attached entity.

So as soon as you start iterating over predictionArray, the code above executes and you have a new entity in your context.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文