2013-08-27 77 views
0
public void ApproveRowTable(string tablename, List<int> idValues) 
{ 
    foreach (var x in idValues) 
    { 
      var context = new SSPModel.sspEntities(); 
      var genRules = (from a in context.GeneralRules 
          where a.ID == x 
          select a).SingleOrDefault(); 
      genRules.Approved_by = GlobalClass.GlobalVar; 
      genRules.Approved_on = DateTime.Now; 
      context.SaveChanges(); 
    } 
} 

在我的查詢(from a in context.GeneralRules ...)我想,使其上的一個參數(表名)的查詢的基礎,而不是我必須去,並在供應表的名稱查詢(因爲它現在正在做)。任何方式我可以得到它做到..基本..從context.TABLENAME -- TABLENAME是一個參數,將被傳遞時,函數被調用。幫助LINQ到實體 - 動態查詢

+2

所有的實體是否都具有屬性'ID','Approved_by'和'Approved_on'?如果是,他們是否繼承了這些屬性的基本抽象類? –

+0

使用動態查詢時,您的意思是「動態LINQ」作爲庫的名稱或「我希望我的查詢是動態的」? – xanatos

+0

你也許認爲「通用查詢」?您是否想將這種方法用於許多不同類型(EF對象=表格)? –

回答

0

我想你想要的方法通用。當你使用EF時,你所有的表都被表示爲對象,所以你不必指定你想要的名字,只需要使用一個通用的參數。

我懷疑我的解決方案是最好的,但它應該工作。但是我必須警告你,反思很慢,很多時候它的用法是不正確的。

public void ApproveRowTable<T>(List<int> idValues) 
{ 
    var context = new SSPModel.sspEntities(); 
    var table = context.GetType().GetProperties().OfType<T>().Single(); 
    var genRules = (from a in table 
          where a.ID == x 
          select a).SingleOrDefault(); 
      genRules.Approved_by = GlobalClass.GlobalVar; 
      genRules.Approved_on = DateTime.Now; 
      context.SaveChanges(); 
} 
+0

而且這種方法對於其他開發人員是公開的,您應該「嘗試 - 捕捉」反射部分,因爲任何人都可能使用具有錯誤類型參數的方法,並且會導致異常。 –

+0

我仍然想按名稱搜索..會幫助我的事業更多 –

+0

我試過了,但我無法找到一種方法。有一個問題,因爲如果你想訪問表的列(EF對象的屬性),你必須首先知道它的類型。你可以通過傳遞一個類型參數來做到這一點,但是我們又一次在泛型是更好的解決方案的情況下。 –

1

如果您的實體類型不是全部實現相同的接口或從相同的類派生,這將是困難的。如果他們這樣做,這是很簡單的:

public partial class GeneralRule : IApprovable {} 

如果您:

// example base type, which your entities would need to implement 
public interface IApprovable 
{ 
    public int ID {get; set;} 
    public string Approved_by {get; set;} 
    public DateTime Approved_on {get; set;} 
} 
//... 
public void ApproveRowTable<T>(List<int> idValues) 
    where T : IApprovable 
{ 
    using(var context = new SSPModel.sspEntities()) 
    { 
     var table = context.Set<T>(); 
     var entities = table.Where(e => idValues.Contains(e.ID)); 
     foreach(var entity in entities) 
     { 
      entity.Approved_by = GlobalClass.GlobalVar; 
      entity.Approved_on = DateTime.Now; 
     } 
     context.SaveChanges(); 
    } 
} 

如果實體類型不實現一個共同的基本類型,那麼你應該通過創建國家執行它的空諧音修改它們不能這樣做,那麼你可以做下面的事情。 (我假設ID是PK,所以我們可以使用Find(),而不需要構建表達式:

public void ApproveTableRows(Type entityType, IEnumerable<int> idsToApprove) 
{ 
    using(var context = new SSPModel.sspEntities()) 
    { 
     var set = context.Set(entityType); 
     if(set == null) 
      throw new ArgumentException("No DbSet found with provided name", "tableSetName"); 

     var approveByProperty = entityType.GetProperty("Approved_by"); 
     var approveOnProperty = entityType.GetProperty("Approved_on"); 
     if(approveByProperty == null || approveOnProperty == null) 
      throw new InvalidOperationException("Entity type does not contain approval properties"); 

     foreach (object id in idsToApprove) 
     { 
      var entityInstance = set.Find(id); 
      approveByProperty.SetValue(entityInstance, GlobalClass.GlobalVar); 
      approveOnProperty.SetValue(entityInstance, DateTime.Now); 
     } 

     context.SaveChanges(); 
    } 
} 

正如你所看到的,這是效率較低,因爲它會發出一個新的查詢每個ID而這個方法可以接受一個實體Type而不是一個字符串,以避免需要通過反射尋找正確的屬性,這可以得到改善,但我想你應該更新你的實體來實現一個共享的接口