0
votes

Combiner le résultat de différentes procédures stockées dans une seule liste en c #

J'essaye de joindre deux listes différentes ensemble en utilisant la méthode Concat comme indiqué ci-dessous. J'ai besoin que la deuxième liste soit ajoutée à la première liste, afin qu'elle puisse devenir une seule.

var term = dc.AgentTerm(Agentcode).ToList();
var hosp = dc.AgentHospCashPlan(Agentcode).ToList();
var life = term.Concat(hosp).ToList();

Mais quand je l'ai essayé, j'obtiens cette erreur.

Erreur 16 Argument d'instance: impossible de convertir de System.Collections.Generic.List en System.Linq.IQueryable C: \ Projet \ IbsMobile \ IbsMobile \ Controllers \ ParamController.cs 506 24 IbsMobile

L'erreur 17 System.Collections.Generic.List ne contient pas de définition pour 'Concat' et la meilleure surcharge de méthode d'extension System.Linq.Queryable.Concat (System.Linq.IQueryable , System.Collections.Generic.IEnumerable ) a des arguments non valides C: \ Project \ IbsMobile \ IbsMobile \ Controllers \ ParamController.cs 506 24 IbsMobile p>

J'ai vérifié en ligne et tout ce que je vois, c'est comment convertir 'System.Linq.IQueryable' en 'System.Collections.Generic.IList'.

Les résultats que je 'm assigning to term et Hosp sont des procédures stockées.

J'ai déjà utilisé la méthode concat sur des listes avec la même classe et cela a bien fonctionné.

Je suppose que cette erreur est due au fait que les ensembles de résultats proviennent de classes différentes.

Je sais que c'est une question novice mais je ne sais pas exactement ce que je je vais mal.


15 commentaires

Je suppose que cette erreur est due au fait que les ensembles de résultats proviennent de classes différentes - si term et host sont des listes de types différents - alors ce n'est pas le cas possible.


Question naïve, quels sont les types de liste term et le type de liste hosp ?


@Fabio, Oui, Ils sont de classes différentes, car ce sont des procédures stockées, ils obtiennent différents ensembles de résultats de la base de données. Je veux ajouter les deux listes ensemble, n'est pas possible de les rejoindre.


Est-il vraiment judicieux de regrouper les deux listes en une seule?


On dirait un problème XY. Pourquoi voulez-vous concaténer des collections de différents types? Comment allez-vous les utiliser. Envisagez de créer une classe qui contient deux propriétés des collections dont vous avez besoin.


Essayez quelque chose comme ceci en utilisant object []: term.Select (x => nouvel objet [] {x.prop1, x.prop2, x.prop3}). Concat (hosp);


@ClintonOkorie - J'adorerais entendre la réponse à la question de Fabio.


@Enigmativity Oh OK, laquelle des questions. Si c'était la raison pour laquelle je concaténais différents types, j'avais quelques procédures stockées chacune avec son jeu de résultats et je devais renvoyer tous les jeux de résultats sous forme de liste unique.


@ClintonOkorie - Désolé, il est impossible de répondre à la question de savoir pourquoi vous essayez de concaténer différents types, car vous vouliez les résultats sous forme de liste unique. C'est comme dire "pourquoi voulez-vous une seule liste - c'est parce que je veux une seule liste". Quelle est la raison de vouloir concaténer / avoir une seule liste?


@Enigmativity Oh d'accord, je comprends.


@ClintonOkorie - Et la raison en est?


@Enigmativity Nous avons différentes procédures stockées, qui retournent différents types de données pour un client particulier, Nous voulons une situation où nous pouvons retourner tous les différents types de données avec un seul appel. J'ai cependant trouvé une solution. J'ai trouvé un moyen d'utiliser une seule procédure stockée, pour appeler plusieurs procédures stockées. De cette façon, je n'ai qu'une seule liste lorsque j'appelle la procédure stockée principale>


@ClintonOkorie - Il existe de nombreuses autres options. Que diriez-vous de renvoyer un tuple ou un type personnalisé?


@Enigmativity Je suis ouvert aux idées, si vous pouvez me montrer, je serais très reconnaissant.


@ClintonOkorie - Terminé.


3 Réponses :


0
votes

Vous ne pouvez pas Concatrer des listes de deux types de sources différents. Voir la signature des fonctions:

public interface IInterface {}
public class AgentTermDTO : IInterface {}
public class AgentHospCashPlanDTO : IInterface {}

Pour ce faire, projetez chaque liste dans un type qui partage le même type de base ou interface. Quelque chose de la structure:

public static System.Collections.Generic.IEnumerable<TSource> Concat<TSource> 
    (this System.Collections.Generic.IEnumerable<TSource> first, 
     System.Collections.Generic.IEnumerable<TSource> second);

ou une solution rapide et sale (n'allez pas pour celle-ci) consiste à convertir chacun en une collection d ' object code > s: list1.Cast().Concate(...)


2 commentaires

Je ne suis pas sûr de bien comprendre la méthode d'interface, pourriez-vous s'il vous plaît m'envoyer un lien ou quelque chose où je peux voir un exemple?


@ClintonOkorie, il dit essentiellement que vous ne pouvez pas directement concater 2 listes de types différents en C #, ils doivent être du même type, pour cela il utilise une interface qui fournit un ensemble de méthodes courantes pour à la fois AgentTermDTO et AgentHospCashPlanDTO à implémenter afin qu'ils soient communs et puissent être concaténés plus tard. En savoir plus sur cette réponse et Covariance .



0
votes

Si vous aviez écrit la définition complète de term et hosp au lieu de var, vous auriez écrit quelque chose comme:

IEnumerable<IMyInterface> myTerms = terms.Select(term => new AgentTerm
    {
         TermResult = term,
    })
    .Cast<IMyInterface>();
IEnumerable<IMyInterface> myHosps = hosps.Select(hosp => new MyHosp
    {
        Hosp = hosp,
    })
    .Cast<IMyInterface>();

var result = myTerms.Concat(myHosps);

Apparemment, ils ne sont pas du même type. Vous ne pouvez concaténer que des séquences de type similaire. Hélas vous avez oublié de nous écrire vos cours. Si un terme et un hosp sont liés, par exemple s'ils ont la même super classe, vous pouvez les convertir en super classe avant de contaténer:

class AgentTerm : IMyInterface
{
     public AgentTerm_Result TermResult {get; set;}

     public int Id => this.TermResult.TermResultId;
     public string Name => this.TermResult.TermResultName;

Cela fonctionne également s'ils implémentez la même interface.

S'il n'y a rien de commun entre eux, vous devriez peut-être reconsidérer l'idée de concaténer ces deux listes. Après tout, à quoi sert la collection de Vaches mélangée à une collection de NewYorkCityBuildings?

Quoi qu'il en soit, si vous pensez vraiment qu'il y a quelque chose de commun , il existe plusieurs solutions pour concaténer les séquences. Bien sûr, vous ne pouvez utiliser que les propriétés qu'ils ont en commun.

Pensez à créer une interface contenant les propriétés auxquelles vous souhaitez accéder:

interface IMyInterface
{
     // Properties that are both in AgentTerm_Result and in AgentHospCashPlan
     int Id {get;}
     string Name {get;}
}

class AgentTerm_Result : IMyInterface {...}
class AgentHospCashPlan : IMyInterface{...}

var result = terms.Cast<IMyInterface>()
     .Concat(hosps.Cast<IMyInterface>();

Si il n'y a pas de propriétés communes, pensez à créer une classe wrapper qui convertit les propriétés en propriétés appropriées:

var result = terms.Cast<CommonSuperClass>()
    .Concat(hosps.Cast<CommonSuperClass>();

}

et similaire pour Hosp p >

List<AgentTerm_Result> terms = ...
List<AgentHospCashPlan_Result> hosps = ...


0 commentaires

0
votes

Si vous souhaitez renvoyer deux listes contenant deux types différents, la meilleure option est de renvoyer un type personnalisé ou même simplement de renvoyer un tuple.

Pour renvoyer un type personnalisé, définissez simplement une classe contenant les valeurs de retour :

var (term, hop) = GetResults();

Vous pouvez maintenant le faire facilement:

public (List<AgentTerm_Result>, List<AgentHospCashPlan_Result>) GetResults()
{
    var Agentcode = "";

    var term = dc.AgentTerm(Agentcode).ToList();
    var hosp = dc.AgentHospCashPlan(Agentcode).ToList();

    return (term, hosp);
}   

Utiliser un tuple est un peu plus facile que vous ne le faites pas besoin de définir quelque chose de nouveau:

public Results GetResults()
{
    var term = dc.AgentTerm(Agentcode).ToList();
    var hosp = dc.AgentHospCashPlan(Agentcode).ToList();

    return new Results { AgentTerms = term, AgentHospCashPlan = hosp };
}

Pour obtenir les résultats du tuple, appelez-le simplement comme ceci:

public class Results
{
    public List<AgentTerm_Result> AgentTerms;
    public List<AgentHospCashPlan_Result> AgentHospCashPlan;
}

Ensuite vous pouvez utiliser les résultats comme deux variables distinctes.


4 commentaires

Merci, j'essaierais les deux. Une question rapide, Supposons que les deux listes ont un champ appelé "Date de création", serait-il possible de trier les valeurs de la liste comme une seule, par ordre décroissant de date de création, quelle que soit la liste à laquelle les valeurs appartiennent?


@ClintonOkorie - Je ne suis pas sûr de ce que vous entendez par «trier les valeurs de la liste comme une seule». Vous avez deux listes, pas une, ce qui signifie qu'elles peuvent avoir des nombres d'éléments différents.


Je comprends que ce sont deux listes, essayant juste de comprendre, s'il y a un moyen de trier les deux listes ensemble comme s'il s'agissait d'une seule liste. Mes excuses si mes questions sont beaucoup, je suis nouveau dans ce domaine.


@ClintonOkorie - Que signifie "trier les deux listes ensemble comme s'il s'agissait d'une seule liste"?