3 votes

compression du code avec les génériques C#

J'ai les 2 méthodes suivantes qui, je pense, pourraient être comprimées en une seule méthode en utilisant des génériques. Ce que j'ai essayé ne peut pas compiler. Je ne sais pas si je peux le faire, mais je ne sais pas si je peux le faire. J'ai besoin de vérifier que 2 champs différents de la table AgeLengths ont au moins une valeur. Str_table a une relation "one to many" avec AgeLengths.

public static bool HasMeanWeight(int id)
{
    MyDataContext dc = new MyDataContext ();
    return  (from s in dc.Str_table 
             where s.SId == id 
             select s.AgeLengths
             .Where(a => a.MeanWeight != null ).Any() == true
            ).FirstOrDefault();
}

public static bool HasNumbersData(int id)
{
    MyDataContext dc = new MyDataContext ();
    return (from s in dc.Str_table 
            where s.sId == id 
            select s.AgeLengths
            .Where(a => a.Numbers  != null).Any() == true
           ).FirstOrDefault();
}

Merci d'avance B

5voto

Adam Houldsworth Points 38632

Mise à jour : Mes excuses, je n'avais pas réalisé qu'il s'agissait de linq to sql. Réponse de Dennis semble avoir raison.

Essayez d'injecter un Func<T, TResult> pour injecter le code différent :

public static bool HasData(int id, Func<AgeLength, object> selector)
{
    MyDataContext dc = new MyDataContext ();
    return (from s in dc.Str_table 
            where s.sId == id 
            select s.AgeLengths
                .Where(a => selector(a) != null)
                .Any())
           .FirstOrDefault();
}

Et appeler ainsi :

HasData(1, a => a.Numbers);
HasData(1, a => a.MeanWeight);

Si le Numbers y MeanWeight se trouvent dans la même hiérarchie d'héritage, alors vous pouvez substituer object avec quelque chose de plus utile, mais dans ce cas object est correct car vous ne faites que tester la nullité.

3voto

Dennis Points 14573

Si vous utilisez des DataContext vous utilisez IQueryable<T> et vous êtes très limité dans ce que vous pouvez écrire dans vos expressions. Vous devez donc passer un expression à votre méthode, et non un prédicat lui-même :

static bool HasData(int id, Expression<Func<AgeLength, bool>> predicate)
{
    using (MyDataContext dc = new MyDataContext())
    {
        return (from s in dc.Str_table
                where s.sId == id
                select s.AgeLengths
                .Any(predicate)
               ).FirstOrDefault();
    }
}

En outre :

  • il y a Any qui accepte l'expression d'un prédicat ;
  • doit être éliminé (voir using ) ;
  • il n'est pas nécessaire d'écrire someBoolExpression == true ; il suffit d'écrire someBoolExpression .

Vous pouvez alors appeler cette méthode comme suit :

HasData(1, a => a.MeanWeight != null);
HasData(1, a => a => a.Numbers  != null);

Notez que le deuxième argument est une expression lambda, et non une méthode.
Ceci est dû à la nature paresseuse des requêtes : vous fournissez un ensemble d'expressions, et le fournisseur correspondant les convertit en SQL approprié.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X