流畅的 NHibernate 映射 IDictionary以聪明的方式
给定这些类:
using System.Collections.Generic;
namespace FluentMappingsQuestion
{
public class Entity
{
public virtual int Id { get; set; }
public virtual IDictionary<string, Property> Properties { get; set; }
}
public class Property
{
public virtual Entity OwningEntity { get; set; }
public virtual string Name { get; set; }
public virtual int Value { get; set; }
public virtual decimal OtherValue { get; set; }
}
}
我如何使用NHibernate(最好是流畅的风格)映射它们,以便这样做是可能的:
[Test]
public void EntityPropertyMappingTest()
{
using (var session = _factory.OpenSession())
{
var entity = new Entity();
// (#1) I would *really* like to use this
entity.Properties["foo"] = new Property { Value = 42, OtherValue = 42.0M };
session.Save(entity);
session.Flush();
// (#2) I would like the entity below to "update itself"
// on .Save or .Flush. I got it to work with .Load()
Assert.AreEqual(42, entity.Properties["foo"].Value);
Assert.AreEqual(42.0M, entity.Properties["foo"].OtherValue);
Assert.AreEqual("foo", entity.Properties["foo"].Name);
Assert.AreEqual(entity, entity.Properties["foo"].Owner);
}
}
我几乎设法用这些映射做到这一点:
// class EntityMap : ClassMap<Entity>
public EntityMap()
{
Id(x => x.Id);
HasMany(x => x.Properties)
.Cascade.AllDeleteOrphan()
.KeyColumn("EntityId")
.AsMap(x => x.Name);
}
// class PropertyMap : ClassMap<Property>
public PropertyMap()
{
Id(x => x.Id);
References(x => x.OwningEntity).Column("EntityId");
Map(x => x.Name).Length(32);
Map(x => x.Value);
{
我遇到的问题:
- 如果我制作
Entity.Properties
.Inverse()
,它开始中断 - 如果我没有做到
.Inverse()
那么 NHibernate 会这样做:INSERT(Entity), INSERT(Property ), UPDATE(Property)
而不仅仅是INSERT(Entity), INSERT(Property)
- 如果我创建
Property.Name
.Not.Nullable( )
,它开始中断 - 如果我不这样做
.Not.Nullable()
,我的数据库模式中有一个漏洞
我应该如何更改我的映射?
Given these classes:
using System.Collections.Generic;
namespace FluentMappingsQuestion
{
public class Entity
{
public virtual int Id { get; set; }
public virtual IDictionary<string, Property> Properties { get; set; }
}
public class Property
{
public virtual Entity OwningEntity { get; set; }
public virtual string Name { get; set; }
public virtual int Value { get; set; }
public virtual decimal OtherValue { get; set; }
}
}
How can I map them using NHibernate (preferably fluent flavor) so that doing this is possible:
[Test]
public void EntityPropertyMappingTest()
{
using (var session = _factory.OpenSession())
{
var entity = new Entity();
// (#1) I would *really* like to use this
entity.Properties["foo"] = new Property { Value = 42, OtherValue = 42.0M };
session.Save(entity);
session.Flush();
// (#2) I would like the entity below to "update itself"
// on .Save or .Flush. I got it to work with .Load()
Assert.AreEqual(42, entity.Properties["foo"].Value);
Assert.AreEqual(42.0M, entity.Properties["foo"].OtherValue);
Assert.AreEqual("foo", entity.Properties["foo"].Name);
Assert.AreEqual(entity, entity.Properties["foo"].Owner);
}
}
I have almost managed to do this with these mappings:
// class EntityMap : ClassMap<Entity>
public EntityMap()
{
Id(x => x.Id);
HasMany(x => x.Properties)
.Cascade.AllDeleteOrphan()
.KeyColumn("EntityId")
.AsMap(x => x.Name);
}
// class PropertyMap : ClassMap<Property>
public PropertyMap()
{
Id(x => x.Id);
References(x => x.OwningEntity).Column("EntityId");
Map(x => x.Name).Length(32);
Map(x => x.Value);
{
The problems I have:
- If I make
Entity.Properties
.Inverse()
, it starts breaking - If I don't make it
.Inverse()
then NHibernate does:INSERT(Entity), INSERT(Property), UPDATE(Property)
instead of justINSERT(Entity), INSERT(Property)
- If I make
Property.Name
.Not.Nullable()
, it starts breaking - If I don't make it
.Not.Nullable()
, I have a hole in my db schema
How should I change my mappings?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我通过指定此映射来解决此问题:
并创建两个
IDictionary
类型的属性:Properties
和InternalProperties
。第一个是第二个之上的代理字典,用于设置Property
条目的OwningEntity
和Name
属性。I worked around this by specifying this mapping:
and creating two properties of type
IDictionary<string, Property>
:Properties
andInternalProperties
. The first one is a proxy dictionary over the second one, and deals with setting theOwningEntity
andName
properties for theProperty
entries.