You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fluent NHibernate实体同时映射表与视图的问题求助

问题:分阶段迁移多租户数据时的NHibernate读写映射问题

场景概述

我们正在将单多租户数据库中部分数据的source of truth迁移至多租户单库模式,因客户数量庞大,迁移分阶段进行。为此创建了视图dbo.vwEntity,逻辑为:数据已迁移则从同义词synEntity取数,未迁移则从原表tblEntities取数。

视图定义SQL

create view dbo.vwEntity
as 
select 
     e.id
    ,case
        when s.IsMigrated = 1 then e_syn.Field1
        else e.Field1
     end                    as 'Field1' /* Migrated Field */
    ,e.Field2                           /* Non-Migrated Field */
from dbo.tblEntities as e
    left outer join dbo.synEntity as e_syn
        on e_syn.Id = e.Id
    inner join dbo.tblSystem as s
        on s.SystemId = e.SystemId;

业务需求

现有一个大型legacy应用,原本是该表所有数据的source of truth:已迁移客户的数据在应用中只读(因此ClassMap<>实体字段标记.Not.Update()),未迁移客户的数据需可更新。但将映射类改为使用新视图后,无法再更新未迁移客户的数据。

尝试的方案及异常

曾尝试用Fluent NHibernate通过EntityName属性实现读写分离的需求,但调用FluentConfiguration的BuildConfiguration()时出现Duplicate class/entity mapping异常。

相关映射类代码

视图映射类

public class EntityMapView : ClassMap<Entity>
{
    public EntityMap()
    {
        Table("vwEntity");
        Id(t => t.Id);
        Map(t => t.Field1).Not.Update();
        Map(t => t.Field2);
    }
}

实体表映射类(添加EntityName前)

public class EntityMapTable : ClassMap<Entity>
{
    public EntityMap()
    {
        Table("tblEntity");
        Id(t => t.Id);
        Map(t => t.Field1);
        Map(t => t.Field2);
    }
}

实体表映射类(添加EntityName后)

public class EntityMapTable : ClassMap<Entity>
{
    public EntityMap()
    {
        Table("tblEntity");
        EntityName("EntityTable");
        Id(t => t.Id);
        Map(t => t.Field1);
        Map(t => t.Field2);
    }
}

异常详情

[DuplicateMappingException: Duplicate class/entity mapping EntityTable]
   NHibernate.Cfg.Mappings.AddClass(PersistentClass persistentClass) +201
   NHibernate.Cfg.XmlHbmBinding.RootClassBinder.Bind(HbmClass classSchema, IDictionary`2 inheritedMetas) +1127
   NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddEntitiesMappings(HbmMapping mappingSchema, IDictionary`2 inheritedMetas) +125
   NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.Bind(HbmMapping mappingSchema) +113
   NHibernate.Cfg.Configuration.AddDeserializedMapping(HbmMapping mappingDocument, String documentFileName) +184

[MappingException: Could not compile the mapping document: (XmlDocument)]
   NHibernate.Cfg.Configuration.LogAndThrow(Exception exception) +117
   NHibernate.Cfg.Configuration.AddDeserializedMapping(HbmMapping mappingDocument, String documentFileName) +444
   NHibernate.Cfg.Configuration.ProcessMappingsQueue() +26
   NHibernate.Cfg.Configuration.AddInputStream(Stream xmlInputStream, String name) +172
   NHibernate.Cfg.Configuration.AddDocument(XmlDocument doc, String name) +344
   FluentNHibernate.PersistenceModel.Configure(Configuration cfg) +842
   FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration() +184

[FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

]

另外,也曾考虑使用SubclassMap<>类并修改视图仅返回已迁移数据,但原表仍存在,会导致已迁移客户的数据出现重复行。

当前环境版本

  • NHibernate : 4.0.4.4000
  • Fluent NHibernate : 2.0.3

因无法升级.NET框架,故无法升级至NHibernate 5.0.0及Fluent NHibernate 2.1.0。

恳请提供解决思路。


内容的提问来源于stack exchange,提问作者John O

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 01:01:06