如何通过全局扩展方法("My Extensions")在LinqPad中查询多个数据库名称?

How to query multiple database names in LinqPad via a global extension method ("My Extensions")?

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

为此,我编写了以下扩展方法,它在 My Extensions(您可以在 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 键同时将多个数据库拖放到查询中 window 以添加它们,您将从该方法中获得附加数据库名称的列表(除第一个数据库外的所有数据库,它是this.Connection.Database.Dump();).

最初我想将扩展方法声明为 "public static" 以便它可用于所有查询,但是当我将其声明为 public 时我得到了消息

CS0051 Inconsistent accessibility: parameter type 'UserQuery' is less accessible than method 'MyExtensions.GetAdditionalDatabaseNames(UserQuery)'


更新: 我尝试了一种解决方法,并在 MyExtensions 中添加了一个 public 通用包装方法 ,如下所示:

// 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: Object reference not set to an instance of an object.


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

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

我的扩展

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

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

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

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

任何 C# 查询 window

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

注意:您可能想知道,为什么 this.Connection.Database 不只是添加到扩展方法内的列表中 - 这是因为 Connection 对象在内部不可访问My Extensions 模块。