在MVC中使用Linq将表与不同数据组合在一起?

时间:2013-02-05 11:50:03

标签: c# asp.net linq entity-framework asp.net-mvc-4

我有两个名为OfflineOrderLineItem.cs和OnlineOrderLineItem.cs的类都有diff命名表,名为offline和Online

因为我希望将两个表数据组合起来搜索并显示两个表中的字段

如何在mvc4中使用linq ???任何想法.....

public virtual IPagedList<OnlineOrderLineItem> SearchOrderLineItems(string PoNumber)
{
     var query1 = (from ol in _offlineOrderLineItemRepository.Table
                   select new
                  {                            
                   ol.Name

                  }).ToList();

     var query2 = (from opv in _onlineOrderLineItemRepository.Table
                   select new
                   {
                    opv.Name

                   }).ToList();

     var finalquery = query1.Union(query2);

     if (!String.IsNullOrWhiteSpace(Name))
     finalquery = finalquery.Where(c => c.Name == Name);
     var orderlineitems = finalquery.ToList(); //its not working  it throw a error
     return new PagedList<OnlineOrderLineItem>(orderlineitems);//error 
    }

错误

cannot convert from 'System.Collections.Generic.List<AnonymousType#1>'
to 'System.Linq.IQueryable<Nop.Core.Domain.Management.OnlineOrderLineItem>'
to 'System.Linq.IQueryable<Nop.Core.Domain.Management.OnlineOrderLineItem>'

2 个答案:

答案 0 :(得分:2)

query1query2是具有string类型的单个属性的匿名类型的列表。 (我认为ol.Nameopv.Name都是string。因此,finalQueryorderlineitems也是这个匿名的集合。通过指定PagedList<T>,您需要传递给构造函数的集合是类型T的枚举。 TOnlineOrderLineItem,但传递给构造函数的枚举是匿名类型,它是一种不同的类型。结果:编译错误。

要解决此问题,我建议您定义一个命名助手类型,您可以使用该类型来合并两种不同类型OfflineOrderLineItemOnlineOrderLineItem

public class OrderLineItemViewModel
{
    public int Id { get; set; }
    public string PoNumber { get; set; }
    public string Name { get; set; }

    // maybe more common properties of `OfflineOrderLineItem`
    // and `OnlineOrderLineItem`     
}

然后您的SearchOrderLineItems方法应返回该帮助程序类型的分页列表:

public virtual IPagedList<OrderLineItemViewModel> SearchOrderLineItems(
    string PoNumber)
{
    var query1 = from ol in _offlineOrderLineItemRepository.Table
                 select new OrderLineItemViewModel
                 {
                     Id = ol.Id,
                     PoNumber = ol.PoNumber,
                     Name = ol.Name,
                     // maybe more properties
                 };
                 // don't use ToList here, so that the later Union and filter
                 // can be executed in the database

    var query2 = from opv in _onlineOrderLineItemRepository.Table
                 select new OrderLineItemViewModel
                 {
                     Id = opv.Id,
                     PoNumber = opv.PoNumber,
                     Name = opv.Name,
                     // maybe more properties
                 };
                 // don't use ToList here, so that the later Union and filter
                 // can be executed in the database

    var finalquery = query1.Union(query2);
    // again no ToList here

    if (!string.IsNullOrWhiteSpace(PoNumber))
        finalquery = finalquery.Where(c => c.PoNumber == PoNumber);

    var orderlineitems = finalquery.ToList(); // DB query runs here

    return new PagedList<OrderLineItemViewModel>(orderlineitems);
}

仅在查询的最后使用ToList很重要。否则,您将所有OnlineOrderLineItem和所有OfflineOrderLineItem的整个表加载到内存中,然后在内存中过滤掉具有给定PoNumber的项目,这将是一个很大的开销和性能损失

答案 1 :(得分:1)

而不是

 var orderlineitems = finalquery.ToList();

尝试

 var orderlineitems = finalquery.AsQueryable();

https://github.com/TroyGoode/PagedList/blob/master/src/PagedList/PagedList.cs开始,PagedList需要IQueryable<T>

Queryable.AsQueryable<TElement> Method