1

我在我的网络应用程序中使用 subsonic 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 Profiler 捕获它)

我的第一个问题是:为什么 Subsonic 要看 Schema?它在生成我的数据层时构建了模式、类和关系?

我的第二个问题是:我可以让它停下来吗?这是可配置的吗?

来自:使用 SubSonic 有没有一种方法可以在没有外键的情况下表达关系?

在运行时 SubSonic(至少 2.x)不依赖任何真正的外键存在。仅在 DAL 生成期间查询信息模式。

这是真的?有没有可能我的配置有问题。

我正在使用 ShareDBConnectionScope,因为多个数据库具有相似的架构但有一些自定义表。

4

1 回答 1

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");
于 2012-02-10T10:03:43.473 回答