2009-08-04 6 views
4

J'ai une classe de réservationautogenerated séquentielle Id avec l'aide de LINQ

public class Booking 
    { 
     public int Id { get; set; } 

     public string From { get; set; } 

     public string To { get; set; } 
    } 

Je crée une liste des réservations avec l'aide de LINQ et je veux un mécanisme avec lequel je veux autogenerate la propriété « Id » incrémenter par 1.

si la liste des réservations contient 10 objet de réservation, puis le premier Id = 1 de l'objet, deuxième Id = 2 et ainsi une ...

toute suggestion

+0

Que voulez-vous dire par «je crée une liste de réservations avec l'aide de linq»? –

+0

Votre meilleur pari est de laisser la base de données gérer ces identifiants uniques en spécifiant une colonne "INT IDENTITY" dans votre table pour contenir les réservations. –

+0

Je n'ai aucune base de données – Miral

Répondre

9

Ce qui suit vous donnera une liste des réservations NOUVEAU avec l'indice prévu dans votre propriété d'identité. Vous pourriez probablement faire quelque chose de similaire à ce mettre à jour la liste existante avec l'index ...

var myBookings = myExistingListOfTen.Select((b, index) => new Booking 
       { 
        Id = index + 1, 
        From=b.From, 
        To=b.To 
       }); 
+0

De cette façon, vous perdez la référence et vous faites une instanciation d'objet unnessecary. – Dykam

+0

Oui, vous faites. OP n'a cependant demandé aucune de ces conditions ... –

+0

Pour moi, c'est la meilleure réponse jusqu'à présent. – jpbochi

0

Je ne sais pas si je comprends bien votre bonne question, mais vous pouvez toujours

ID = bookings.Select(b=>b.ID).Max()+1; 

Je ne sais pas si c'est une bonne idée (ce ne sera pas performant).

+0

La performance serait désastreuse: P. O (n^2) – Dykam

6

Pas sympa, mais ça va marcher. L'astuce consiste à utiliser la surcharge fournissant l'index de l'article.

list = list.Select((item, index) => { item.Id = index; return item; }); 

Cela mettra à jour les réservations existantes, mais vous pouvez également sélectionner une nouvelle instance avec l'ensemble identifiant et éviter ce return laid au coût de duplication des réservations et de perdre les références comme le suggère Scott Ivey. Et bien sûr, vous devez en ajouter un si vous voulez des identifiants uniques. Je trouve cela un peu étrange de générer des ID de cette façon aussi, mais cela pourrait être une solution acceptable si vous obtenez une liste de nouvelles réservations sans ID et que vous voulez les générer. Dans ce cas, les identifiants ne doivent évidemment pas commencer par zéro ou un, mais par le plus grand identifiant plus un.

+0

+1 - bonne réponse Daniel. –

+0

Excellente réponse. Thnx. Son générique qui peut être utilisé n'importe où .... – sapatelbaps

1

Pour pouvoir effectuer les opérations suivantes:

bookings.ForEach((booking, index) => booking.Id = index + 1); 

Vous devez placer à suivre extrait quelque part dans une classe statique:

public static IEnumerable<T> ForEach<T>(
     this IEnumerable<T> source, 
     Action<T, int> action) 
    { 
     int index = 0; 
     foreach (T element in source) { 
      action(element, index++); 
     } 
    } 
    return source; 
} 

Ofcourse suit fonctionnera aussi:

int index = 0; 
foreach (var booking in bookings) { 
    booking.Id = ++index; 
} 
1
public class Booking 
{ 
    private static int BookingCount = 1; 

    public Booking() 
    { 
     Id = BookingCount++; 
    } 

    public int Id { get; set; } 

    public string From { get; set; } 

    public string To { get; set; } 
} 
+0

C'est une mauvaise pratique, n'est-ce pas? Quel est le questionneur veut deux collections? – Dykam

+0

cela va créer un compteur global ... et aussi, je vais vous suggérer d'utiliser Interlocked pour la sécurité du fil –

4

Sûrement si je t est une propriété sur l'objet dont vous voulez que la valeur soit cohérente de l'invocation à l'invocation. La réservation 'A' ne devrait pas avoir un ID différent selon l'endroit où il existe dans la liste. Si vous voulez simplement l'index de l'élément dans la liste, ne le stockez pas comme une propriété de l'élément, mais dérivez-le de sa position dans la liste.

+1

a voté pour cela. toutes les autres suggestions ne tiennent pas compte du fait que les réservations peuvent non seulement être ajoutées, mais aussi retirées de la collection. cependant, la question n'est pas assez claire. –

0

Bien que je suis d'accord avec @tvanfosson (+1), si vous voulez vraiment garder un ID dans Booking je pense que cela devrait être mis sur la construction de la réservation. Vous pourriez avoir quelque chose comme un contexte de réservation où chaque contexte créerait des réservations avec des numéros de série:

public class Booking 
    { 
     protected Booking() { } 
     public int Id { get; set; } 

     public string From { get; set; } 

     public string To { get; set; } 
    } 

    public class BookingContextFactory 
    { 
     private int count; 

     public BookingContextFactory() : this(0) { } 
     public BookingContextFactory(int startValue) 
     { 
      count = startValue; 
     } 

     public Booking CreateBooking(string from, string to) 
     { 
      return new InternalBooking { Id = count++, From = from, To = to }; 
     } 

     private class InternalBooking : Booking 
     { 
      public InternalBooking() : base() { } 
     } 
    } 
Questions connexes