web-dev-qa-db-fra.com

Comment ajouter un nouvel enregistrement à une variable IQueryable?

Les résultats IQueryable sont interrogés à partir de ma base de données à l'aide de LINQ. Comment puis-je ajouter un nouvel enregistrement au résultat IQueryable?.

22
silent200

Voulez-vous l'ajouter à la base de données ou simplement à la liste des résultats que d'autres éléments, tels que la liaison de données, vont utiliser?

Si c'est le premier cas, vous devrez utiliser l'opération d'ajout normale pour le type de LINQ que vous utilisez, mais pour la représentation sous forme de tableau plutôt que pour IQueryable. Les requêtes ne lisent que les données.

Si c'est le dernier cas, utilisez Enumerable.Concat pour concaténer votre séquence existante (IQueryable) avec une nouvelle contenant vos entrées supplémentaires (un tableau ferait l'affaire ici ou une liste), et utiliser le résultat pour la liaison, etc. Il est probablement utile d’utiliser AsEnumerable () d’abord pour vous assurer que Enumerable est utilisé à la place de Queryable. Par exemple:

IQueryable<string> names = [...];
names = names.AsEnumerable().Concat(new[] { "(None)", "(Add new)" });
36
Jon Skeet

Vous devriez d'abord le convertir en liste;

IQueryable<int> foo = new SomeQueryable<int<();
List<int> list = foo.ToList();
list.Add(5);

ou en utilisant Concat

IQueryable<int> foo = new SomeQueryable<int<();
foo = foo.Concat(new int[]{5});

EDIT: bien sûr, vous devez réaffecter foo.

11
Ali Ersöz

La réponse simple est que, sauf si vous ajoutez l'enregistrement au magasin de données sous-jacent interrogé par Iqueryable, vous ne pouvez pas ajouter un nouvel enregistrement dans un IQueryable. Donc, si vous utilisez LinqToSql, vous devez ajouter une ligne dans la table interrogée par IQueryable pour "ajouter" une ligne dans IQueryable.

N'oubliez pas qu'un IQueryable n'est pas un ensemble de résultats, c'est une requête. Tant que vous n'utilisez pas quelque chose comme .ToList (), IQueryable n'évaluera pas un jeu de résultats et, plus important encore, IQueryable ne sera pas accroché à cet ensemble de résultats. Il crée une liste et place les résultats dans. Cela signifie donc que si vous appelez deux fois ToList () sur un Iqueryable, celui-ci s’exécutera et interrogera la base de données deux fois. Peu importe que cela soit inefficace.

Donc, si vous regardez les exemples que d'autres ont utilisés ci-dessus, un simple changement de AsEnumerable () en ToList () résoudra probablement vos problèmes.

Quelque chose comme: 

dcDataContext db = new dcDataContext();
var query = from c in db.tblSexes
              select new { c.SexCode, c.SexName };

var results = query.ToList().Concat(new[] { new { SexCode = -1, SexName = "Please select your Gender" } });

//or even better now that it's a list
var results = query.ToList().Add(new { SexCode = -1, SexName = "Please select your Gender" });

SelectList sliSex = new SelectList(results, "SexCode", "SexName");
4
Jero

C'est peut-être une très vieille question, je voudrais ajouter plus d'explication et un échantillon ici

si vous utilisez IQueryable<YourObject>, vous devez d'abord le convertir en IEnumerable<YourObject>

détails supplémentaires sur IEnumerable: 

Retour de IEnumerable <T> vs. IQueryable <T>

par

IQueryable<YourObject> iqueryResult = // ..... your LinQ or whatever
IEnumerable<YourObject> enumResult = iqueryResult.AsEnumerable();

alors, pour ajouter vous pouvez le faire par

enumResult = enumResult.Concat(new[] {new YourObject()
                 { 
                    //.... 
                 } 
             });

échantillon de code réel

var iquery_QRDTR = from rrp in P_QCDTR
        select new WebRequestData
        {
             ros_chk_id = rrp.CHECKIN_ID,
             ros_img = rrp.EMPLOYEE_ASSOCIATE.IMAGE_URL
        };

var enum_QRDTR = iquery_QRDTR.AsEnumerable();

enum_QRDTR = enum_QRDTR.Concat(new[] {new WebRequestData()
             {
             ros_chk_id = 16,
             ros_img = "http://link.to.image/profile.jpg" 
             } });
3
Sruit A.Suk

Essaye ça:

var query = from c in db.clClinics select c; 

var results = query.ToList().Concat(new clClinic[] { new clClinic()});  
1
ayman

Vous pouvez utiliser l'union

IQueryable<int> foo = new SomeQueryable<int>();
IQueryable<int> foo2 = new SomeQueryable<int>();
foo = foo.Union(foo2);
0
Nurlan T

Définir explicitement les propriétés des types anonymes. Essaye ça:

dcDataContext db = new dcDataContext();
var results = from c in db.tblSexes
              select new { c.SexCode, c.SexName };
results = results.AsEnumerable().Concat(new[] { new { SexCode = -1, SexName = "Please select your Gender"} });
SelectList sliSex = new SelectList(results, "SexCode", "SexName");

Edit: Vous devez indiquer les types exacts de vos propriétés. Je veux dire si c'est int, vous devez le préciser. Je suppose que SexCode est un "long" et par défaut -1 est un "int". Si vous transformez -1 en long (ou le type de SexCode), le problème sera résolu. 

Voici la solution exacte si le type de SexCode est long. 

dcDataContext db = new dcDataContext();
var results = from c in db.tblSexes
              select new { c.SexCode, c.SexName };
results = results.Concat(new[] { new { SexCode = -1L, SexName = "Please select your Gender"} });
SelectList sliSex = new SelectList(results, "SexCode", "SexName");
0
Ali Ersöz

Parce que le résultat est IQueryable, vous devriez y lancer

  dcDataContext db = new dcDataContext();
var results = from c in db.tblSexes
              select new { c.SexCode, c.SexName };
results = results.AsEnumerable().Concat(new[] { new { SexCode = -1, SexName = "Please select your Gender"} }).AsQueryable();
SelectList sliSex = new SelectList(results, "SexCode", "SexName");

Ou sans casting

results = results.Union (new [] {new { SexCode = -1, SexName = "Veuillez sélectionner votre sexe"}})

0
Dincer Uyav