我有一个数据库,其中包含一个描述多个实体的表,其中一列是另一个保存该实体数据的数据库的名称。所有实体数据库都与列出它们的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,并想知道,由于每个数据库具有相同的模式,可能有一个我可以用某种方式实现此目的的基类。
答案 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;
}
}