web-dev-qa-db-fra.com

Mettre à jour les enregistrements en utilisant LINQ

Je dois définir une valeur dans une table pour un sous-ensemble de lignes. En SQL, je ferais ceci:

UPDATE dbo.Person SET is_default = 0 WHERE person_id = 5

Y a-t-il un moyen de faire cela dans LINQ?

J'utilise actuellement le:

var result = (from p in Context.People....)

notation.

Existe-t-il une méthode de mise à jour que je peux utiliser? Ou dois-je obtenir tous les enregistrements, puis les mettre à jour un par un dans un Foreach?

Est-ce le moyen le plus efficace, si cela est même possible?

(from p in Context.person_account_portfolio where p.person_id == personId select p)
   .ToList()
   .ForEach(
       x =>
       x.is_default =
       false);
46
Craig

Cela a fonctionné mieux.

(from p in Context.person_account_portfolio 
 where p.person_id == personId select p).ToList()
                                        .ForEach(x => x.is_default = false);

Context.SaveChanges();
52
Craig

Je suppose que person_id est la clé primaire de la table Person. Voici comment mettre à jour un seul enregistrement:

Person result = (from p in Context.Persons
              where p.person_id == 5
              select p).SingleOrDefault();

result.is_default = false;

Context.SaveChanges();

et voici comment mettre à jour plusieurs enregistrements:

List<Person> results = (from p in Context.Persons
                        where .... // add where condition here
                        select p).ToList();

foreach (Person p in results)
{
    p.is_default = false;
}

Context.SaveChanges();
54
ekad

En complément de la réponse acceptée, votre code pourrait sembler plus cohérent lorsque vous utilisez la syntaxe de la méthode LINQ:

Context.person_account_portfolio
.Where(p => person_id == personId)
.ToList()
.ForEach(x => x.is_default = false);

.ToList() est nécessaire car .ForEach () est défini uniquement sur List<T>, pas sur IEnumerable<T>. Sachez simplement que .ToList() va exécuter la requête et charger TOUTES les lignes correspondantes de la base de données avant d'exécuter la boucle.

9
ChriPf

Vous avez deux options pour autant que je sache:

  1. Effectuez votre requête, parcourez-la pour modifier les entités, puis appelez SaveChanges().
  2. Exécutez une commande SQL comme vous l'avez mentionné en haut de votre question. Pour savoir comment faire cela, regardez cette page .

Si vous utilisez l'option 2, vous perdez une partie de l'abstraction fournie par Entity Framework, mais si vous devez effectuer une mise à jour très volumineuse, cela peut constituer le meilleur choix pour des raisons de performances.

6
Steve

Oui. Vous pouvez utiliser foreach pour mettre à jour les enregistrements dans linq.Il n’existe aucune dégradation des performances.

vous pouvez vérifier que l'opérateur standard Where est implémenté à l'aide de la construction rendement introduite en C # 2.0.

l'utilisation du rendement présente un avantage intéressant , à savoir que la requête n'est pas réellement évaluée avant d'être itérée, soit avec une instruction foreach, soit manuellement à l'aide des méthodes GetEnumerator et MoveNext sous-jacentes.

Par exemple,

var query = db.Customers.Where (c => c.Name.StartsWith ("A"));
query = query.Where (c => c.Purchases.Count() >= 2);
var result = query.Select (c => c.Name);

foreach (string name in result)   // Only now is the query executed!
   Console.WriteLine (name);

Les opérateurs exceptionnels sont les suivants: Premièrement, ElementAt, Sum, Average, Tous, Tous, ToArray et ToList forcent l'évaluation immédiate des requêtes.

Donc pas besoin de faire peur pour utiliser foreach pour update le résultat linq.

Dans votre cas, l'exemple de code donné ci-dessous sera utile pour mettre à jour de nombreuses propriétés,

 var persons = (from p in Context.person_account_portfolio where p.person_name == personName select p);

//TO update using foreach

foreach(var person in persons)
{
//update property values
}  

J'espère que ça aide ...

3
ManirajSS

Oui, vous devez obtenir tous les enregistrements, les mettre à jour, puis appeler SaveChanges.

2
MarcinJuraszek

Étrangement, pour moi, il s'agit de SubmitChanges par opposition à SaveChanges:

    foreach (var item in w)
    {
        if (Convert.ToInt32(e.CommandArgument) == item.ID)
        {
            item.Sort = 1;
        }
        else
        {
            item.Sort = null;
        }
        db.SubmitChanges();            
    }                   
1
boateng
public ActionResult OrderDel(int id)
    {
        string a = Session["UserSession"].ToString();
        var s = (from test in ob.Order_Details where test.Email_ID_Fk == a && test.Order_ID == id select test).FirstOrDefault();
        s.Status = "Order Cancel By User";
        ob.SaveChanges();
        //foreach(var updter in s)
        //{
        //    updter.Status = "Order Cancel By User";
        //}


        return Json("Sucess", JsonRequestBehavior.AllowGet);
    } <script>
            function Cancel(id) {
                if (confirm("Are your sure ? Want to Cancel?")) {
                    $.ajax({

                        type: 'POST',
                        url: '@Url.Action("OrderDel", "Home")/' + id,
                        datatype: 'JSON',
                        success: function (Result) {
                            if (Result == "Sucess")
                            {
                                alert("Your Order has been Canceled..");
                                window.location.reload();
                            }
                        },
                        error: function (Msgerror) {
                            alert(Msgerror.responseText);
                        }


                    })
                }
            }

        </script>
0
SHUBHASIS