Subsonic 3.0 和大型 SQL 数据库

发布于 2024-08-06 10:41:20 字数 64 浏览 3 评论 0原文

有没有办法将生成的代码限制为数据库中的特定表?我的数据库有几百个表,我只想在其中少数几个上使用 SubSonic。

Is there a way to limit the code generated to specific tables in a database? My database has a few hundred tables and I only really want to use SubSonic on a handfull of them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鸢与 2024-08-13 10:41:21

沃伦,我也遇到了和你一样的情况。
你可以尝试我的解决方案。
我的解决方案是一表一T4模板。

您应该做的是:

  1. 在 SQLServer.ttinclude 中,将 LoadTables 方法替换为以下代码:

List LoadTables(params string[]tables)
{
var 结果=新列表();

string sql = TABLE_SQL;
if(tables.Length > 0)
{
  StringBuilder sb = new StringBuilder();
  foreach(string table in tables){
    sb.AppendFormat("'{0}',", table);
  }
  sql += " and TABLE_NAME in (" + sb.Remove(sb.Length - 1, 1).ToString() + ")";
}

//pull the tables in a reader
using(IDataReader rdr=GetReader(sql))
{
    while(rdr.Read())
    {
        Table tbl=new Table();
        tbl.Name=rdr["TABLE_NAME"].ToString();
        tbl.Schema=rdr["TABLE_SCHEMA"].ToString();
        tbl.Columns=LoadColumns(tbl);
        tbl.PrimaryKey=GetPK(tbl.Name);
        tbl.CleanName=CleanUp(tbl.Name);
        tbl.ClassName=Inflector.MakeSingular(tbl.CleanName);
        tbl.QueryableName=Inflector.MakePlural(tbl.ClassName);

        //set the PK for the columns
        var pkColumn=tbl.Columns.SingleOrDefault(x=>x.Name.ToLower().Trim()==tbl.PrimaryKey.ToLower().Trim());
        if(pkColumn!=null)
            pkColumn.IsPK=true;

        tbl.FKTables=LoadFKTables(tbl.Name);

        result.Add(tbl);
    }
}

foreach(Table tbl in result)
{
    //loop the FK tables and see if there's a match for our FK columns
    foreach(Column col in tbl.Columns)
    {
        col.IsForeignKey=tbl.FKTables.Any(
            x=>x.ThisColumn.Equals(col.Name,StringComparison.InvariantCultureIgnoreCase)
        );
    }
}
return result;

  1. 在 Context.tt 中,找到代码 vartables = LoadTables(); 并替换为以下代码:

    var dir = System.IO.Path.GetDirectoryName(Host.TemplateFile) + "\\Entities";
    var fileNames = Directory.GetFiles(dir, "*.tt");
    string[] tableNames = new string[fileNames.Length];
    for(int i=0; i < fileNames.Length; i++)
    {
    tableNames[i] = System.IO.Path.GetFileName(fileNames[i]).Replace(".tt","");
    }
    vartables = LoadTables(tableNames);

  2. 创建一个名为“Entities”的新文件夹,并将 Settings.ttinclude 和 SQLServer.ttinclude 复制到新文件夹中。

  3. 在 ActiveRecord.tt 中,找到代码 vartables = LoadTables(); 并替换为以下代码:

    var tableName = System.IO.Path.GetFileName(Host.TemplateFile).Replace(".tt","");
    vartables = LoadTables(tableName);

完成步骤1到步骤4后,当你想从指定的表生成一个新的ActiveRecord类时,你应该做的是:

  1. 创建一个新的T4模板,其名称与指定表的表名。
  2. 将 ActiveRecord.tt 代码复制到新的 T4 模板
  3. 为新的 T4 模板生成代码
  4. 为 Context.tt 模板生成代码

顺便说一句:我的英语不是很好,所以...

Warren, I also met the same situation as you.
You can try my solution.
My solution is one table one T4 template.

What you should do is :

  1. In SQLServer.ttinclude, replace LoadTables method with the code below:

List LoadTables(params string[] tables)
{
var result=new List();

string sql = TABLE_SQL;
if(tables.Length > 0)
{
  StringBuilder sb = new StringBuilder();
  foreach(string table in tables){
    sb.AppendFormat("'{0}',", table);
  }
  sql += " and TABLE_NAME in (" + sb.Remove(sb.Length - 1, 1).ToString() + ")";
}

//pull the tables in a reader
using(IDataReader rdr=GetReader(sql))
{
    while(rdr.Read())
    {
        Table tbl=new Table();
        tbl.Name=rdr["TABLE_NAME"].ToString();
        tbl.Schema=rdr["TABLE_SCHEMA"].ToString();
        tbl.Columns=LoadColumns(tbl);
        tbl.PrimaryKey=GetPK(tbl.Name);
        tbl.CleanName=CleanUp(tbl.Name);
        tbl.ClassName=Inflector.MakeSingular(tbl.CleanName);
        tbl.QueryableName=Inflector.MakePlural(tbl.ClassName);

        //set the PK for the columns
        var pkColumn=tbl.Columns.SingleOrDefault(x=>x.Name.ToLower().Trim()==tbl.PrimaryKey.ToLower().Trim());
        if(pkColumn!=null)
            pkColumn.IsPK=true;

        tbl.FKTables=LoadFKTables(tbl.Name);

        result.Add(tbl);
    }
}

foreach(Table tbl in result)
{
    //loop the FK tables and see if there's a match for our FK columns
    foreach(Column col in tbl.Columns)
    {
        col.IsForeignKey=tbl.FKTables.Any(
            x=>x.ThisColumn.Equals(col.Name,StringComparison.InvariantCultureIgnoreCase)
        );
    }
}
return result;

}

  1. In Context.tt, find code var tables = LoadTables(); and replace with the code below:

    var dir = System.IO.Path.GetDirectoryName(Host.TemplateFile) + "\\Entities";
    var fileNames = Directory.GetFiles(dir, "*.tt");
    string[] tableNames = new string[fileNames.Length];
    for(int i=0; i < fileNames.Length; i++)
    {
    tableNames[i] = System.IO.Path.GetFileName(fileNames[i]).Replace(".tt","");
    }
    var tables = LoadTables(tableNames);

  2. Create a new folder named "Entities" and copy the Settings.ttinclude and SQLServer.ttinclude to the new folder.

  3. In ActiveRecord.tt, find code var tables = LoadTables(); and replace with the code below:

    var tableName = System.IO.Path.GetFileName(Host.TemplateFile).Replace(".tt","");
    var tables = LoadTables(tableName);

After finish step1 to step4, when you want to generate a new ActiveRecord Class from a specified table, what you should do is:

  1. Create a new T4 template that has the same name as the specified table's tablename.
  2. Copy the ActiveRecord.tt code to the new T4 template
  3. Generate code for the new T4 template
  4. Generate code for the Context.tt template

BTW: My engilsh is not very well, so...

聽兲甴掵 2024-08-13 10:41:20

如果表名与您感兴趣的表之一匹配,您可以修改 T4 模板以限制函数调用。现在,它仅检查 ExcludedTables。看起来只添加一个白名单也是非常简单的。试试这个。

在 Settings.ttinclude 中,复制

string[] ExcludeTables = new string[]{
"sysdiagrams",
"BuildVersion",
};

声明,然后粘贴名为“IncludeTables”的新数组声明。将您的表名称添加到其中。然后在 Structs.tt、ActiveRecord.tt 和 Context.tt 中搜索“ExcludeTables”。无论您在哪里找到它,请添加对包含的表格的检查。所以改变,

if(!ExcludeTables.Contains(tbl.Name))

if(!ExcludeTables.Contains(tbl.Name) 
    && (IncludeTables.Length == 0 || IncludeTables.Contains(tbl.Name))

应该可以让你开始。

You can modify the T4 templates to just limit the function call if the table name matches one of the tables you're interested in. Right now, it just checks for ExcludedTables. It looks like it would be pretty trivial to just add a whitelist as well. Try this.

In Settings.ttinclude, copy the

string[] ExcludeTables = new string[]{
"sysdiagrams",
"BuildVersion",
};

declaration, and paste a new array declaration called "IncludeTables". Add your table names to it. Then in Structs.tt, ActiveRecord.tt and Context.tt, do a search for "ExcludeTables". Wherever you find it, add in a check for your included tables. So change,

if(!ExcludeTables.Contains(tbl.Name))

to

if(!ExcludeTables.Contains(tbl.Name) 
    && (IncludeTables.Length == 0 || IncludeTables.Contains(tbl.Name))

That should get you started.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文