将来自不同存储过程的结果合并到c#

时间:2019-03-04 10:21:06

标签: c# linq

我正尝试使用Concat方法将两个不同的列表连接在一起,如下所示。 我需要将第二个列表添加到第一个列表中,以便它可以作为一个清单。

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

但是当我尝试时,出现此错误。

  

错误16实例参数:无法从System.Collections.Generic.List<IbsMobile.AgentTerm_Result>转换为System.Linq.IQueryable<IbsMobile.AgentHospCashPlan_Result> C:\ Project \ IbsMobile \ IbsMobile \ Controllers \ ParamController.cs 506 24 IbsMobile

     

错误17 System.Collections.Generic.List<IbsMobile.AgentTerm_Result>不包含'Concat'的定义,最佳扩展方法重载System.Linq.Queryable.Concat<TSource>(System.Linq.IQueryable<TSource>, System.Collections.Generic.IEnumerable<TSource>)具有一些无效的参数C:\ Project \ IbsMobile \ IbsMobile \ Controllers \ ParamController.cs 506 24 IbsMobile

我在线检查了一下,所看到的只是如何将'System.Linq.IQueryable'转换为'System.Collections.Generic.IList'。

我分配给term和Hosp的结果来自存储过程。

我以前在具有相同类的列表上使用过concat方法,并且效果很好。

我猜这是因为结果集来自不同的类。

我知道这是一个新手问题,但我不确定自己在做什么错。

3 个答案:

答案 0 :(得分:0)

您不能Concat列出两种不同来源类型的列表。查看函数签名:

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

仍要这样做,将每个列表投影到共享相同基本类型或接口的某种类型。结构的一部分:

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

或者一种快速而又肮脏的解决方案(不要这样做)是将每个类型强制转换为object s的集合:list1.Cast<object>().Concate(...)

答案 1 :(得分:0)

如果您要编写term和hosp的完整定义而不是var,那么您应该编写以下内容:

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

显然,它们不是同一类型。您只能串联相似类型的序列。 las,您忘了给我们写课。如果一个术语和一个医院相关,例如,如果它们具有相同的超类,则可以在污染之前将它们转换为超类:

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

如果它们实现相同的接口,这也将起作用。

如果它们之间没有共同之处,那么也许您应该重新考虑有关串联这两个列表的想法。毕竟,Cows的集合与NewYorkCityBuildings的集合混合在一起的用途是什么?

无论如何,如果您真的认为有一些共同点,那么可以使用多种解决方案来连接序列。当然,您只能使用它们共有的属性。

考虑创建一个包含要访问的属性的接口:

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>();

如果没有通用属性,请考虑创建一个将属性转换为适当属性的包装器类:

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

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

}

和类似的医院

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);

答案 2 :(得分:0)

如果要返回包含两种不同类型的两个列表,最好的选择是返回自定义类型,甚至只是返回一个元组。

要返回自定义类型,只需定义一个类来保存返回值:

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

现在您可以轻松地做到这一点:

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

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

使用元组稍微容易一些,因为您不需要定义任何新内容:

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);
}   

要获取元组的结果,只需像这样调用它:

var (term, hop) = GetResults();

然后,您可以将结果用作两个单独的变量。