代码之家  ›  专栏  ›  技术社区  ›  Matt

如何通过全局扩展方法(my extensions)在linqpad中查询多个数据库名?

  •  0
  • Matt  · 技术社区  · 6 年前

    我试图在多连接场景中查询linqpad中的其他数据库名称。

    为此,我编写了以下扩展方法,但在 我的扩展 (您可以在linqpad中声明全局扩展的位置)-但是当放置在新的普通linqpad查询中时,它可以正常工作:

    public static class MyExtensions
    {
        // Write custom extension methods here. They will be available to all queries.
    
        // get list of additional databases used. Pass "this" (of type UserQuery)
        internal static List<string> GetAdditionalDatabaseNames(this UserQuery uq)
        {
    
            var props = uq.GetType().GetProperties();
            var result = new List<string>();
            foreach (var db in props.Where(
                                   w => w.PropertyType.Name == "TypedDataContext").Distinct())
            {
                result.Add(db.Name);
            }
            return result;
        }
    }
    

    用法示例:

    void Main()
    {
        this.Connection.Database.Dump();
        this.GetAdditionalDatabaseNames().Dump();
    }
    

    按住ctrl键,同时将多个数据库拖放到查询窗口中以添加它们,您将从该方法中获得其他数据库名称的列表(除第一个数据库之外的所有数据库,在 this.Connection.Database.Dump(); )

    最初我想将扩展方法声明为 “公共静电” 所以它对所有查询都是可用的,但是当我声明它是公共的时,我得到了消息

    CS0051可访问性不一致:参数类型“userquery”的可访问性低于方法“myextensions.getadditionaldatabasenames(userquery)”。


    更新: 我尝试了一个变通方法,并添加了 公共泛型包装方法 里面 MyExtensions 如下:

    // Wrapper to be able to use it from outside of My Extensions
    public static List<string> GenericAdditionalDatabaseNames<T>(this T userQuery)
    {
        return GetAdditionalDatabaseNames(userQuery as UserQuery);
    }
    

    但是当我在查询中使用它时,我现在得到了一个不同的错误:

    nullreferenceexception:对象引用未设置为对象的实例。


    不必在每个查询中都放置上面的代码,我可以做什么来解决这个问题?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Matt    6 年前

    我刚刚找到了一个适合我的解决方法:对问题中的更新代码进行重构,如下所示:

    我的扩展

    public static class MyExtensions
    {
        public static List<string> GetAdditionalDatabaseNames<T>(this T userQuery)
        {
    
            var props = userQuery.GetType().GetProperties();
            var result = new List<string>();
            foreach (var db in props.Where(
                                   w => w.PropertyType.Name == "TypedDataContext").Distinct())
            {
                result.Add(db.Name);
            }
            return result;
        }
    }
    

    不同的是,这次我 将调用内部方法的另一个扩展方法包装起来。

    但它为什么有效呢?它接受所有类型的对象,并且由于它使用反射,所以它不关心作为参数传递的类型。上面问题中的解决方法不起作用,因为它试图将其转换为用户查询-因为转换不起作用,它通过了 null 导致了nullreferenceexception。

    现在您可以在示例中提到的任何查询窗口中使用它。要获取所有数据库名称,您可以

    任何C查询窗口

    void Main()
    {
        var dbNames=this.GetAdditionalDatabaseNames(); dbNames.Add(this.Connection.Database);
        dbNames.Dump();
    }
    

    注: 你可能会想,为什么 this.Connection.Database 不仅仅是添加到扩展方法内的列表中-这是因为连接对象在 My Extensions 模块。