2010-07-01 49 views
0

我試圖找到並運行一個CompiledQuery給定的名稱。如何通過名稱訪問已編譯的查詢,然後如何調用委託?如何使用委託名稱獲取CompiledQuery

這裏只要我能得到 - 我得到的錯誤「錯誤綁定到目標方法」

public class ActivityRepository 
{ 
    private readonly ActivityDataContext _db; 

    public ActivityRepository() 
    { 
     _db = new ActivityDataContext(); 
    } 

    public static Func<ActivityDataContext, int, IQueryable<ProjectObject>> 
     GetCompiledLatestProjects = CompiledQuery.Compile 
      ((ActivityDataContext db, int projectId) => 
      from c in db.projectObjects 
      where c.projectId == projectId 
      select c); 

    public static Func<ActivityDataContext, Guid, IQueryable<Report>> 
     GetCompiledReports = CompiledQuery.Compile 
      ((ActivityDataContext db, Guid itemId) => 
      from c in db.Reports 
      where c.reportObjectId == itemId 
      select c); 

//其他編譯查詢ommitted,但結果是實現一個共同的接口IQueryable的對象IProjectObject

delegate IQueryable<IProjectObject> MyDelegate(); 

    static MyDelegate GetByName(object target, string methodName) 
    { 
      return (MyDelegate)Delegate.CreateDelegate 
       (typeof(MyDelegate), target, methodName); 
    } 

    public IList<Results> GetResults(string reportName) 
    { 
      IQueryable<ProjectObject> projectItems = GetLatestProjectObjects(projectId, quantity); 
     foreach (projectObject o in projectItems) 
     { 
      MyDelegate del = GetByName(this, reportName); 
      var dbReport = (IProjectObject) GetCompiledReports(_db, o.itemId).FirstOrDefault(); 
// add results to List and return 
     } 
    } 
} 

回答

0

你也許可以做的努力,以確定類型的任何領域Func鍵< ...>有一個DataContext作爲返回IQueryable的第一個參數一些長篇大論方式,但你可能會發現它容易得多,只是添加一個自定義屬性:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] 
public class DynamicQueryAttribute : Attribute { } 

...然後您可以添加到您的領域:

[DynamicQuery] 
public static Func<ActivityDataContext, int, IQueryable<ProjectObject>> 
    GetCompiledLatestProjects = CompiledQuery.Compile 
     ((ActivityDataContext db, int projectId) => 
     from c in db.projectObjects 
     where c.projectId == projectId 
     select c); 

您可以再選擇基於該查詢,它的名字:

public static IQueryable<IProjectObject> ExecuteQuery(Type ownerType, string name, params object[] args) 
{ 
    var query = typeof(ownerType) 
     .GetFields(BindingFlags.Public | BindingFlags.Static) 
     .Where(f => 
       (f.GetCustomAttributes(typeof(DynamicQueryAttribute), false).Length > 0) 
       && (f.Name.ToLowerInvariant() == name.ToLowerInvariant())) 
     .Select(f => (Delegate) f.GetValue(null)) 
     .SingleOrDefault(); 

    if (query == null) 
     return null; 

    return (IQueryable<IReportObject>)query.DynamicInvoke(args); 
} 

用法:

var results = ExecuteQuery(
    typeof(ActivityRepository), 
    "GetCompiledLatestProjects", 
    dataContext, 
    projectId); 

希望幫助:)

+0

偉大的解決方案 - 我沒有想過在這裏使用屬性,但這實際上是一個完美的地方。謝謝你的幫助。 – Andrew 2010-07-02 13:49:46

+0

如果你覺得他們有幫助,那麼接受答案會很好:) – 2010-07-02 14:26:28