简化我的Linq查询和联合

时间:2014-09-19 16:33:27

标签: c# linq entity-framework

我有以下Linq查询,我从两个不同的表中使用相同的过滤器和连接检索数据;最后结合结果集。

            var plannedReceiptsResult = db.OMS_Planned_Receipts.Where(p => p.Product == product && p.PeriodID >= StartPeriod && p.PeriodID <= EndPeriod)
            .Join(db.Periods, c => c.PeriodID, o => o.PeriodID, (c, o) => new { c, o })
          .Select(b => new PivotViewModel
          {
              Product = b.c.Product,
              PeriodID = b.c.PeriodID,
              SiteID = b.c.SiteID,
              Value = b.c.Value,
              Activity = "Planned Receipts",
              PeriodStart = b.o.Period_Start,
              PeriodEnd = b.o.Period_End,
              PeriodDescription = b.o.Display
          });

        var systemForecastResult = db.OMS_System_Forecast.Where(p => p.Product == product && p.PeriodID >= StartPeriod && p.PeriodID <= EndPeriod)
               .Join(db.Periods, c => c.PeriodID, o => o.PeriodID, (c, o) => new { c, o })
          .Select(b => new PivotViewModel
          {
              Product = b.c.Product,
              PeriodID = b.c.PeriodID,
              SiteID = b.c.SiteID,
              Value = b.c.Value,
              Activity = "System Forecast",
              PeriodStart = b.o.Period_Start,
              PeriodEnd = b.o.Period_End,
              PeriodDescription = b.o.Display
          });

        var activityResult = plannedReceiptsResult.Union(systemForecastResult);

我需要对另外8个表执行相同的操作,最后将它们的结果集联合起来。我的所有表都具有相同的模式。我希望用委托或方法简化这个。请指教。

另请注意,我按照applying global filters article

使用带有IDBSet过滤功能的EF 5

我认为应该采用以下方法,但我不确定应该如何调用它。

    public interface IEntity
{
    Int16 TenantID { get; set; }
    string Product { get; set; }
    string SiteID { get; set; }
    int PeriodID { get; set; }
    double? Value { get; set; }
}

        public static void UnionActivity<T>(IDbSet<T> source, IQueryable<DAL.Period> jointSource,
    string product, string activity, int StartPeriod, double EndPeriod, ref List<PivotViewModel> unionSet) where T : class, IEntity
    {

        unionSet = unionSet.Union(source.Where(p => p.Product == product && p.PeriodID >= StartPeriod && p.PeriodID <= EndPeriod)
           .Join(jointSource, c => c.PeriodID, o => o.PeriodID, (c, o) => new { c, o })
           .Select(b => new PivotViewModel
           {
               Product = b.c.Product,
               PeriodID = b.c.PeriodID,
               SiteID = b.c.SiteID,
               Value = b.c.Value,
               Activity = activity,
               PeriodStart = b.o.Period_Start,
               PeriodEnd = b.o.Period_End,
               PeriodDescription = b.o.Display
           })).ToList();
    }

我试过以下但是语法错误:

        List<PivotViewModel> activityResult1 = new List<PivotViewModel>();
        ViewerModel.UnionActivity<System.Data.Entity.IDbSet<DAL.OMS_Planned_Receipts)>(db.OMS_Planned_Receipts, db.Periods, product, "Planned Receipts", StartPeriod, iEndPeriod, ref activityResult1);

2 个答案:

答案 0 :(得分:1)

我不确定它是否正常,但由于所有实体类都具有相同的属性,我们可以创建一个接口并使实体类使用部分类来实现它。有了这个接口,我们就可以创建一个从IQueryable中提取数据的方法。

像这样。

public interface IEntity
{
    string Product { get; set; }
    int PeriodID { get; set; }
    object SiteID { get; set; }
    object Value { get; set; }
}

public partial class OMS_Planned_Receipt : IEntity // Don't know the exact name of your entity class
{
}

public partial class OMS_System_Forecast : IEntity 
{
}

private static IQueryable<PivotViewModel> SelectObjects(IQueryable<IEntity> source,IQueryable<PeriodEntity> jointSource, string product, int StartPeriod, int EndPeriod)
    {
       return source.Where(p => p.Product == product && p.PeriodID >= StartPeriod && p.PeriodID <= EndPeriod)
          .Join(jointSource, c => c.PeriodID, o => o.PeriodID, (c, o) => new { c, o })
          .Select(b => new PivotViewModel
         {
             Product = b.c.Product,
             PeriodID = b.c.PeriodID,
             SiteID = b.c.SiteID,
             Value = b.c.Value,
             Activity = "System Forecast",
             PeriodStart = b.o.Period_Start,
             PeriodEnd = b.o.Period_End,
             PeriodDescription = b.o.Display
         });
    }

因此,您可以将此方法称为

var receipts = SelectObjects(db.OMS_Planned_Receipts, db.Periods, product, StartPeriod, EndPeriod);
var forecasts = SelectObjects(db.OMS_System_Forecast, db.Periods, product, StartPeriod, EndPeriod);

答案 1 :(得分:0)

以下示例应该适合您。

public void Load() 
{

    List<PivotViewModel> activityResult = new List<PivotViewModel>();
    MyLinq(db.OMS_Planned_Receipts, db.Periods, "System ForeCast", ref activityResult);
    MyLinq(db.OMS_System_Forecast, db.Periods, "System ForeCast", activityResult);

    //activityResult has unionized result        
}

private void MyLinq(IEnumerable<MyData> myData, IEnumerable<MyPeriod> periods, string activity, ref IEnumerable<PivotViewModel> unionSet)
{
    unionSet = unionSet.Union
    (
        myData.Where(p => p.Product == product && p.PeriodID >= StartPeriod && p.PeriodID <= EndPeriod)
        .Join(periods, c => c.PeriodID, o => o.PeriodID, (c, o) => new { c, o })
        .Select(b => new PivotViewModel
        {
            Product = b.c.Product,
            PeriodID = b.c.PeriodID,
            SiteID = b.c.SiteID,
            Value = b.c.Value,
            Activity = activity,
            PeriodStart = b.o.Period_Start,
            PeriodEnd = b.o.Period_End,
            PeriodDescription = b.o.Display
        })
    ).ToList();
}