2014-09-19 85 views
2

我有以下Linq查詢,其中我從兩個不同的表中檢索具有相同過濾器和連接的數據;最後結合結果集。簡化我的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個表執行相同的操作,最後將它們的結果集合在一起。我所有的表都有相同的模式。我希望用一個委託或方法來簡化它。請指教。

同時請注意,我使用EF 5 IDBSet過濾按applying global filters article


我覺得下面的方法應該是,但我不知道我應該如何調用它。

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

什麼是OMS_System_Forecast和OMS_Planned_Receipts的集合類型?這些是同一類型的集合嗎? – loopedcode 2014-09-19 16:44:31

+0

你看看這個答案嗎? http://stackoverflow.com/a/23178704/1798889似乎是真正接近你在找什麼。 – CharlesNRice 2014-09-19 16:49:47

+0

嗨@loopedcode;是的,它們是同一類型但不同表格的集合。 – 2014-09-19 16:59:44

回答

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(); 
} 
+0

這是使用LINQ來對象,但OP的代碼是一個EF問題。你還假設所有的表都是相同的類型;我看不出有這種情況。 – Servy 2014-09-19 17:15:15

+0

另外,當你扔掉結果時,你沒有正確地將結果聯合在一起。 – Servy 2014-09-19 17:16:20

+0

的確,我看到他已經設置了EF標籤。沒有注意到它。 – loopedcode 2014-09-19 17:16:47

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

你可以建議如何解決此錯誤:參數1:無法從'System.Data.Entity.IDbSet '轉換爲'System.Linq.IQueryable 2014-09-22 08:46:55

+0

你沒有忘記寫一些類似「public partial class OMS_Planned_Receipts:IEntity」嗎? – 2014-09-22 08:58:19

+0

你如何訪問你的桌子? 我使用'dbContext.Set ()',它返回一個實現IDbSet和IQueryable的DbSet 類型的項。 – 2014-09-22 09:01:52