Fluent NHibernate 错误:实体“ClassMap`1”没有映射的 ID
我正在将以前的项目从使用普通 NHibernate hbm.xml 映射转换为 Fluent NHibernate。目前,我陷入了让这项工作发挥作用的最后步骤之一。我为 DefaultAutomappingConfiguration 添加了一个派生类来修改我的 ID 命名约定。字符串“Id”附加到类名中:
public override bool IsId(FluentNHibernate.Member member)
{
return member.Name == member.DeclaringType.Name + "Id";
}
这应该使“Agency”在名为“AgencyId”的字段中具有 ID。相反,我收到此错误:
The entity 'ClassMap`1' doesn't have an Id mapped. Use the Id method to map your identity property. For example: Id(x => x.Id).
{Name = "ClassMap`1" FullName = "FluentNHibernate.Mapping.ClassMap`1[[BackendDb.Model.Agency, BackendDb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
我在 IsId 函数上设置了断点以查看发生了什么:
{Property: Cache}
{Name = "ClassMap`1" FullName = "FluentNHibernate.Mapping.ClassMap`1[[BackendDb.Model.Agency, BackendDb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
这是什么?该对象不是我创建的。所有其他对象都可以很好地通过此函数,而我真正想要映射的对象则返回正确的值。
我的会话工厂看起来像这样:
var cfg = new MapConfig();
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(m => m.Server(@".\SqlExpress")
.Database("{some dbname}")
.TrustedConnection()))
.Mappings(m =>
m.AutoMappings
.Add(AutoMap.AssemblyOf<Agency>(cfg))
)
.BuildSessionFactory();
令人烦恼的是,这似乎以某种方式导致我在开发数据库中测试 Fluent NHibernate 的三个表被清空。我勒个去?
I'm converting a previous project from using normal NHibernate hbm.xml mappings to Fluent NHibernate. Currently, I'm stuck on what should be one of the last steps to getting this working. I've added a derived class for DefaultAutomappingConfiguration to modify my ID naming convention. The string "Id" is appended to the class name:
public override bool IsId(FluentNHibernate.Member member)
{
return member.Name == member.DeclaringType.Name + "Id";
}
This should make "Agency" have an ID in a field named "AgencyId". Instead, I'm getting this error:
The entity 'ClassMap`1' doesn't have an Id mapped. Use the Id method to map your identity property. For example: Id(x => x.Id).
{Name = "ClassMap`1" FullName = "FluentNHibernate.Mapping.ClassMap`1[[BackendDb.Model.Agency, BackendDb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
I made a breakpoint on the IsId function to see what's going on:
{Property: Cache}
{Name = "ClassMap`1" FullName = "FluentNHibernate.Mapping.ClassMap`1[[BackendDb.Model.Agency, BackendDb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
What is this? The object is not something I've created. Every other object passes through this function fine, and the ones I actually wanted to map are returning the proper value.
My Session factory looks something like this:
var cfg = new MapConfig();
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(m => m.Server(@".\SqlExpress")
.Database("{some dbname}")
.TrustedConnection()))
.Mappings(m =>
m.AutoMappings
.Add(AutoMap.AssemblyOf<Agency>(cfg))
)
.BuildSessionFactory();
Annoyingly, it seems that this somehow caused the three tables I was testing Fluent NHibernate on in my dev database to be emptied. What the hell?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
sessionfactory 尝试根据以下指令自动映射包含
Agency
类的程序集中的所有类:Add(AutoMap.AssemblyOf(cfg))
。由于程序集中有一个AgencyMap
,而ClassMap
没有Id
属性,因此 FNH 会引发错误。如果您想使用
ClassMap
配置,而不是(或除了)声明自动映射配置之外,请声明一个流畅的映射:如果您不需要 AutoMappings,请删除`.AutoMappings。添加'指令。
但是,如果您想使用 AutoMappings,您需要告诉 FNH 您想要映射哪些类。为了处理这个问题,我通常定义一个标记接口:
然后,在从
DefaultAutomappingConfiguration
派生的类中,我告诉 FNH 仅映射具有该接口的类(您可以限制映射的类,但是您可以看起来合适):为了处理主键映射,我创建了一个约定类:
最后,我将 SessionFactory 配置为使用配置/约定类:
The sessionfactory is trying to automap all classes in the assembly that contains your
Agency
class based on this directive:Add(AutoMap.AssemblyOf<Agency>(cfg))
. Since you have anAgencyMap
in the assembly andClassMap<>
does not have anId
property, FNH is throwing an error.If you want to use
ClassMap<>
configurations, instead of (or in addition to) declaring an automapping configuration, declare a fluent mapping:If you don't need AutoMappings, remove the `.AutoMappings.Add' directive.
However, if you want to use AutoMappings, you need to tell FNH what classes you want to map. To handle this, I usually define a marker interface:
Then, in the class that I derive from
DefaultAutomappingConfiguration
, I tell FNH to only map the classes that have that interface (you can limit the mapped classes however you see fit):To handle the primary key mapping, I create a convention class:
Finally, I configure my SessionFactory to use the configuration/convention classes:
您不能将 ClassMap 与自动映射器结合使用,除非您还配置自动映射器以忽略您正在使用 ClassMap 的实体及其各自的映射文件。
就我而言,我碰巧使用自定义属性来指示应该自动映射的类,因此我可以将我不想映射到 .dll 中的各种垃圾扔掉,而无需 Fluent 尝试自动映射it:
在我的
DefaultAutomappingConfiguration
重写类中:当然,如果您只是将自动映射的实体保留在与其他类不同的命名空间中,则不需要检查属性。
You can't use
ClassMap
in combination with the automapper unless you also configure the automapper to ignore the Entites for which you are using ClassMap and their respective mapping files.In my case, I happen to use a custom attribute to indicate classes which should be automapped, so I can toss all sorts of garbage I don't want mapped into my .dll without having Fluent try to automap it:
And in my
DefaultAutomappingConfiguration
override class:Of course, you don't need to check for an attribute if you just keep your automapped entities in a different namespace from other classes.