我可以在LINQPad脚本中动态引用多个数据库吗?

时间:2016-01-26 09:09:08

标签: linqpad

我有一个数据库,其中包含一个描述多个实体的表,其中一列是另一个保存该实体数据的数据库的名称。所有实体数据库都与列出它们的SQL Server位于同一个SQL Server上,并且都具有相同的模式。

我知道我可以使用Ctrl-drag将其他数据库添加到我的脚本中,但我真正想要的是从数据库名称动态执行此操作。这样的事情。

var entities = ParentDatabase.EntityList
    .Where(e => ??)
    .Select(e => new { e.Id, e.DatabaseName });

var results = new List<ResultCarrier>();

foreach (var entity in entities)
{
    results.AddRange(
        GetDataContextFor(entity.DatabaseName).SomeTable
            .Select(t => new ResultCarrier() 
                { 
                    EntityId = e.Id, 
                    Column1 = t.Column1,
                    Column2 = t.Column2,
                    ... 
                }));
}

// further process combined results

这可能吗?

我看到其中一个数据库的类型是LINQPad.User.DatabaseNameTypes.TypedDataContext,并想知道,由于每个数据库具有相同的模式,可能有一个我可以用某种方式实现此目的的基类。

2 个答案:

答案 0 :(得分:3)

TypedDataContext是您的基类,您只需创建一个新实例并将其传递给sql连接字符串。

您可以使用

找到当前的连接字符串
this.Connection.ConnectionString.Dump();

例如,我使用集成安全性,我有一个小例程,遍历我服务器中的所有数据库并转储表,所以我使用以下例程。

var databases = ExecuteQuery<String>("SELECT name FROM sys.databases").ToList();

foreach(var r in databases)
{
    switch (r)
    {
        case "master" :
        case "tempdb" :
        case "model" :
        case "msdb" :
            break;
        default:
           try
           {
               string newConnectionString = String.Format("Data Source={0};Integrated Security=SSPI;Initial Catalog={1};app=LINQPad", this.Connection.DataSource, r);

               var dc = new TypedDataContext(newConnectionString);

               dc.Table.Dump(r);

            }
            catch (Exception ex)
            {
                ex.Message.Dump(r);
            }
            break;

      }

}

答案 1 :(得分:0)

@ sgmoore的回答让我走上正轨。我没有在LINQPad中遇到过ExecuteQuery,我能够用它来实现我想要的。下面是我最终得到的代码。我现在将它扩展为进一步从服务中检索数据并将其加入databaseLocations以得出我所追求的最终结果。

void Main()
{
    var organisations = ExecuteQuery<OrganisationCarrier>(@"
        SELECT do.GroupId [Id], o.sOrganisationName [Name], o.sConnectDatabase [Database]
          FROM dbo.Organisation o
          INNER JOIN dynamix.Organisations do ON o.liOrgID = do.OrganisationID
          INNER JOIN dynamix.OrganisationFeatures oft ON do.OrganisationKey = oft.OrganisationKey
          INNER JOIN dynamix.Features ft ON oft.FeatureKey = ft.FeatureKey
          WHERE ft.FeatureName = 'LightningLocations'").ToList();

    var databaseLocations = new List<LocationExtract>();

    foreach (var organisation in organisations)
    {
        this.Connection.ConnectionString = $"Data Source={this.Connection.DataSource};Integrated Security=SSPI;Initial Catalog={organisation.Database};app=LINQPad";

        databaseLocations.AddRange(ExecuteQuery<LocationCarrier>(@"
            SELECT dml.DmxLocationId [Id], ml.sLocationName [Name], ml.bDeleted [IsDeleted]
                FROM dynamix.MapLocations dml
                INNER JOIN dbo.MapLocations ml ON dml.FmLocationId = ml.liLocationID")
            .Select(l => new LocationExtract(organisation.Id, l.Id, l.Name, l.IsDeleted)));
    }

    databaseLocations.Dump();
}

class OrganisationCarrier
{
    public long Id { get; set; }
    public string Name { get; set; }
    public string Database { get; set; }
}

class LocationCarrier
{
    public long Id { get; set; }
    public string Name { get; set; }
    public bool IsDeleted { get; set; }
}

class LocationExtract
{
    public long OrganisationId { get; }
    public long LocationId { get; }
    public string Name { get; }
    public bool IsDeleted { get; }

    public LocationExtract(long organisationId, long locationId, string name, bool isDeleted)
    {
        OrganisationId = organisationId;
        LocationId = locationId;
        Name = name;
        IsDeleted = isDeleted;
    }
}