mfe*_*eis 4 nhibernate orm fluent-nhibernate
我在.NET4.0库中使用FluentNHibernate 1.4.0进行NHibernate 3.3.3-SP1映射.我正在为我的类型层次结构使用"table-per-inheritance"方法,如下所示:
-- Different process types potentially use
-- different types of reference values
CREATE TABLE ProcessTypes
(Id INT PRIMARY KEY)
-- Contains reference values for value comparisons
CREATE TABLE ProcessReferenceValues
(Id INT PRIMARY KEY IDENTITY(1,1),
ProcessTypeId INT FOREIGN KEY REFERENCES ProcessTypes(Id),
FloatReferencesValue FLOAT NULL,
IntReferenceValue INT NULL)
Run Code Online (Sandbox Code Playgroud)
// POCOs
class ProcessReferenceValues
{
public virtual int Id { get; set; }
public virtual ProcessTypes ProcessType { get; set; }
public virtual float? FloatReferenceValue { get; set; }
public virtual int? IntReferenceValue { get; set; }
}
class IntProcessReferenceValues : ProcessReferenceValues { }
class FloatProcessReferenceValues : ProcessReferenceValues { }
enum ProcessTypeName : int
{
IntProcess = 1,
FloatProcess = 2
}
class ProcessTypes
{
public virtual int Id { get; set; }
public virtual ProcessTypeName Name { get; set; }
}
// FluentNHibernate Mappings
class ProcessReferenceValuesMap
: FluentNHibernate.Mapping.ClassMap<ProcessReferenceValues>
{
public ProcessReferenceValuesMap()
{
string processTypeId = "ProcessTypeId";
this.Id(x => x.Id);
this.Map(x => x.FloatReferenceValue).Nullable();
this.Map(x => x.IntReferenceValue).Nullable();
// Here is the tricky bit
this.References(x => x.ProcessType, processTypeId);
this.DiscriminateSubClassesOnColumn(processTypeId);
}
}
class IntProcessReferenceValuesMap
: FluentNHibernate.Mapping.SubclassMap<IntProcessReferenceValues>
{
public IntProcessReferenceValuesMap()
{
this.DiscriminatorValue((int)ProcessTypeName.IntProcess);
}
}
class FloatProcessReferenceValuesMap
: FluentNHibernate.Mapping.SubclassMap<FloatProcessReferenceValues>
{
public FloatProcessReferenceValuesMap()
{
this.DiscriminatorValue((int)ProcessTypeName.FloatProcess);
}
}
class ProcessPeriodTypesMap : FluentNHibernate.Mapping.ClassMap<ProcessPeriodTypes>
{
public ProcessPeriodTypesMap()
{
this.ReadOnly();
this.Id(x => x.Id, "id");
this.Map(x => x.Name, "id").ReadOnly().CustomType<PeriodTypeName>();
}
}
Run Code Online (Sandbox Code Playgroud)
虽然从数据库读取工作就像一个魅力 - 正确选择了适当的子类 - 保存一个新的流程参考值给了我一个例外:
// Reading
var processType =
(from type in session.Query<ProcessTypes>()
where type.Name == ProcessTypeName.IntProcess
select type).FirstOrDefault(); // OK, finds the IntProcess
var referenceValues =
(from val in session.Query<ProcessReferenceValues>()
select val).ToList(); // OK, finds the appropriate subclasses
Run Code Online (Sandbox Code Playgroud)
// Inserting
var processType = new ProcessTypes
{
Id = (int)ProcessTypeName.IntProcess
};
var referenceValue = new ProcessReferenceValues
{
FloatReferenceValue = 0.7f,
IntReferenceValue = null,
ProcessType = processType // Needs the appropriate ProcessType
};
session.Save(referenceValue); // <- BOOM!
Run Code Online (Sandbox Code Playgroud)
Error dehydrating property value for ProcessReferenceValues.ProcessType
Invalid Index 2 for OleDbParameterCollection with Count=2.
bei System.Data.OleDb.OleDbParameterCollection.RangeCheck(Int32 index)
bei System.Data.OleDb.OleDbParameterCollection.GetParameter(Int32 index)
bei System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item(Int32 index)
bei NHibernate.Type.Int32Type.Set(IDbCommand rs, Object value, Int32 index) in p:\nhibernate-core\src\NHibernate\Type\Int32Type.cs:Zeile 60.
bei NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index) in p:\nhibernate-core\src\NHibernate\Type\NullableType.cs:Zeile 182.
bei NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) in p:\nhibernate-core\src\NHibernate\Type\NullableType.cs:Zeile 122.
bei NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) in p:\nhibernate-core\src\NHibernate\Type\ManyToOneType.cs:Zeile 50.
bei NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) in p:\nhibernate-core\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:Zeile 2410.
像往常一样,在困难时期我召唤了gooragle,问题似乎是this.DiscriminateSubClassesOnColumn(processTypeId)与this.References(x => x.ProcessType, processTypeId)映射增加了冲突.当我删除前者插入成功但我想要子类映射和我还需要能够设置ProcessReferenceValues.ProcessType何时添加新实例ProcessReferenceValues来区分子类.
是否可以区分列上的子类,同时引用相同类型的同一列?
非常感谢帮助,必须有办法做到这一点......
提前thx!
没有问题的类和映射
// POCOs
class ProcessValue
{
public virtual int Id { get; set; }
public abstract ProcessValueType Type { get; }
}
class IntProcessValue : ProcessValue
{
public virtual int? Value { get; set; }
public override ProcessValueType Type { get { return ProcessValueType.Int; } }
}
class FloatProcessValue : ProcessValue
{
public virtual float? Value { get; set; }
public override ProcessValueType Type { get { return ProcessValueType.Float; } }
}
enum ProcessValueType : int
{
Int = 1,
Float = 2
}
Run Code Online (Sandbox Code Playgroud)
// FluentNHibernate Mappings
class ProcessValueMap : ClassMap<ProcessValue>
{
public ProcessValueMap()
{
string processTypeId = "ProcessValueTypeId";
Id(x => x.Id);
// just so you can query by type enum also. Querying by clr Type is already implemented
Map(x => x.Type, processTypeId).CustomType<ProcessValueType>().ReadOnly().Access.None();
DiscriminateSubClassesOnColumn(processTypeId);
}
}
class IntProcessValueMap : SubclassMap<IntProcessValue>
{
public IntProcessValueMap()
{
Map(x => x.Value).Nullable();
DiscriminatorValue((int)ProcessValueType.Int);
}
}
class FloatProcessValueMap : SubclassMap<FloatProcessValue>
{
public FloatProcessValueMap()
{
Map(x => x.Value).Nullable();
DiscriminatorValue((int)ProcessValueType.Float);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2526 次 |
| 最近记录: |