我在我的网络应用程序中使用了亚音速2.2。我有一个包含许多表的数据库。 当外键的数量太多时,使用此查询对GetSchema的第一次调用会挂起很长时间:
SELECT
FK_Table = FK.TABLE_NAME,
FK_Column = CU.COLUMN_NAME,
PK_Table = PK.TABLE_NAME,
PK_Column = PT.COLUMN_NAME,
Constraint_Name = C.CONSTRAINT_NAME,
Owner = FK.TABLE_SCHEMA
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
INNER JOIN
(
SELECT i1.TABLE_NAME, i2.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
)
PT ON PT.TABLE_NAME = PK.TABLE_NAME
我跟踪了SQLDataProvider中的GetTableSchema调用。
在我的代码中,我正在查询一个跟踪带有动态列的表的表: (不确定它是否重要。只是应用程序中数据库的第一个查询)
SubSonic.Select select3 = new SubSonic.Select();
SubSonic.SqlQuery
query3.Where("[MY_TABLE_NAME_IS_PRIVATE]").IsEqualTo("[MY_TABLE_NAME_IS_PRIVATE]");
List<[MY_TABLE_NAME_IS_PRIVATE]> subSonicList3 = query3.ExecuteTypedList<[MY_TABLE_NAME_IS_PRIVATE]>();
调用query3.Where(...)
时调用GetSTableSchema
(使用SQL事件探查器捕获它)
我的第一个问题是:为什么Subsonic会关注Schema?它在生成我的数据层时构建了模式以及类和关系吗?
我的第二个问题是:我可以让它停止吗?这是可配置的吗?
来自:With SubSonic is there a way to express relationships without foreign keys?
在运行时,SubSonic(至少2.x)不依赖任何真正的外键存在。仅在DAL生成期间查询信息模式。
这是真的吗?我的配置中是否有可能出错?
我正在使用ShareDBConnectionScope,因为多个数据库具有相似的模式,但有一些自定义表。
答案 0 :(得分:0)
我遇到了同样的问题。
在我第一次调用SubSonic之前,我已将此代码放入我的应用程序中。
这将从生成的代码加载模式,而不是在运行时查询information_schema
foreach (var type in this.GetType().Assembly.GetExportedTypes())
{
if (type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.FullName != null && type.BaseType.FullName.StartsWith("SubSonic.ActiveRecord`1"))
{
type.GetMethod("GetTableSchema", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null);
}
}
我还修改了MySqlInnoDbDataProvider的SubSonic代码以避免运行时的InformationSchema查询(我更喜欢异常并修复代码)
/// <summary>
/// Gets the table schema.
/// </summary>
/// <param name="tableName">Name of the table.</param>
/// <param name="tableType">Type of the table.</param>
/// <returns></returns>
public override TableSchema.Table GetTableSchema(string tableName, TableType tableType)
{
if (schemaCollection.ContainsKey(tableName))
return schemaCollection[tableName];
// Avoid querying the information_schema @ runtime
if (DataService.Provider.Name == "MyProviderName")
throw new InvalidOperationException("Querying Information_Schema at runtime is not a good idea. The caller should use DataService.GetTableSchema(tableName, providerName) instead of DataService.Provider.GetTableSchema(providerName) to force the use of the cached TableSchema definition");