我有一个数据库,其中包含一个描述多个实体的表,其中一列是保存该实体数据的另一个数据库的名称。所有实体数据库都与列出它们的数据库位于同一 SQL Server 上,并且都具有相同的架构。
我知道我可以使用 Ctrl 拖动将其他数据库添加到我的脚本中,但我实际上想要的是从数据库名称动态执行此操作。像这样的东西。
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,并且想知道由于每个数据库具有相同的架构,是否可能有一个基类,我可以以某种方式使用它来实现这一点。
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;
}
}
@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;
}
}