【问题标题】:how to use a delegate to get by name a CompiledQuery如何使用委托通过名称获取 CompiledQuery
【发布时间】:2010-07-01 16:33:19
【问题描述】:

我正在尝试查找并运行给定名称的 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);

//其他编译查询省略,但结果是实现了通用接口IProjectObject的IQueryable对象

    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
         }
     }
}

【问题讨论】:

    标签: c# linq delegates typeof linq.compiledquery


    【解决方案1】:

    您可能会采取一些冗长的方法来尝试使用 DataContext 作为返回 IQueryable 的第一个参数来识别 Func<...> 类型的任何字段,但是您可能会发现仅添加自定义属性要容易得多:

    [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);
    

    希望有帮助:)

    【讨论】:

    • 很好的解决方案 - 我没有想到在这里使用属性,但这实际上是他们的理想场所。感谢您的帮助。
    • 如果您觉得有帮助,最好接受答案 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    相关资源
    最近更新 更多