简体   繁体   English

Fluent NHibernate - 覆盖映射中的表名

[英]Fluent NHibernate - Override table names from mapping

I'm using Fluent NHibernate to map my NHibernate models. 我正在使用Fluent NHibernate来映射我的NHibernate模型。

Now i came accros the problem, that I want to prefix all my tables with an underscore in some cases . 现在我遇到了问题, 在某些情况下我希望在所有表格前加下划线。 So i can't just change the Table(...) definition in my mapping, I have to do it from the outside. 所以我不能只在映射中更改Table(...)定义,我必须从外部进行。

What I've got so far: 到目前为止我得到了什么:

Model: 模型:

class Foo
{
    public virtual int Id { get; set; }
}

class FooMapping : ClassMap<Foo>
{
    Table("foo_table");

    Id(x => x.Id).Column("foo_id");
}

Somewhere in my controller: 在我的控制器的某个地方:

/*...*/
if (yourehappyandyouknowit)
{
    Fluently.Configure()
    /*...*/
        .Conventions.Add(Table.Is(x => "_" + x.TableName));
    /*...*/
}

This allways puts out "foo_table" and not "_foo_table". 这总是推出“foo_table”而不是“_foo_table”。

When I comment out the Table(...) definition, it is working like a charm... But I need to have the Table(...) set within the mapping. 当我注释掉Table(...)定义时,它就像魅力......但我需要在映射中设置Table(...)

As long as you define 只要你定义

Table("foo_table");

you'll have to update all those places and add your prefix to it. 你必须更新所有这些地方并添加你的前缀。 Would be best to use a constant value defined somewhere that if you have to change that again, it's all in one place... 最好使用一个定义的常量值,如果你必须再次改变它,它就在一个地方......

public const string TABLE_PREFIX = "_";

and then use it 然后使用它

Table(TABLE_PREFIX + "foo_table");

to easily refactor, simply search for Table(" and replace it with Table(TABLE_PREFIX + " in all files... 轻松重构,只需搜索Table("并将其替换为Table(TABLE_PREFIX + "在所有文件中...

You can try using the following convention: 您可以尝试使用以下约定:

using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.Instances;
using FluentNHibernate.Conventions.AcceptanceCriteria;
using FluentNHibernate.Conventions.Inspections;

namespace MyDatabaseProject.Conventions
{
    public class UnderscoreTableNameConvention : IClassConvention
    {
        public void Accept(IAcceptanceCriteria<IClassInspector> criteria)
        {

        }
        public void Apply(IClassInstance instance)
        {
            instance.Table("_" + instance.TableName);
        }
    }
}

Then you'll need to build your session factory with something like this: 然后你需要用这样的东西建立你的会话工厂:

sessionFactory = Fluently.Configure(normalConfig)
                  .Mappings(m =>
                      m.FluentMappings
                      .AddFromAssemblyOf<OrderMap>()
                      .Conventions.AddFromAssemblyOf<UnderscoreTableNameConvention>())
                      .ProxyFactoryFactory("NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate")
                  .BuildSessionFactory();

Any changes to your mappings after you've built your session factory via Fluent NHibernate will require that you rebuild your session factory with the new table mappings you want. 在通过Fluent NHibernate构建会话工厂后对映射所做的任何更改都需要使用所需的新表映射重建会话工厂。

The above answers gave me a sql server error because of "`" around the table name. 由于表名周围有“`”,上面的答案给了我一个sql server错误。 They also didn't include all type of mappings, such as subclasses and collections. 它们也不包括所有类型的映射,例如子类和集合。

This is what worked for me: 这对我有用:

using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.AcceptanceCriteria;
using FluentNHibernate.Conventions.Inspections;
using FluentNHibernate.Conventions.Instances;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestingNhibernate
{
    public class UnderscoreTableNameConvention : IClassConvention, IJoinedSubclassConvention,  ICollectionConvention
    {
        public readonly string PrependToTableName = "_"; 

        public void Apply(IClassInstance instance)
        {
            instance.Table(GetTableName(instance.EntityType.Name));
        }

        public void Apply(IJoinedSubclassInstance instance)
        {
            instance.Table(GetTableName(instance.EntityType.Name));
        }

        public void Apply(ICollectionInstance instance)
        {
            instance.Table(GetTableName(instance.EntityType.Name));
        }

        private string GetTableName(string originalName)
        {
            return string.Format("`{0}{1}`", PrependToTableName, originalName);
        }
    }
}

Like @[Cole W] mentioned, you need to build the sessionFactory with the conventions: 就像@ [Cole W]提到的那样,你需要使用约定构建sessionFactory:

sessionFactory = Fluently.Configure(normalConfig)
                  .Mappings(m =>
                      m.FluentMappings
                      .AddFromAssemblyOf<OrderMap>()
                      .Conventions.AddFromAssemblyOf<UnderscoreTableNameConvention>())
                      .ProxyFactoryFactory("NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate")
                  .BuildSessionFactory();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM