成功获得示例程序后,我现在开始了 使用Fluent NHibernate进行实际工作 - 尝试在我的项目类中使用Automapping 层次结构。
这是一个科学的仪器应用程序,我的课程 映射具有几个属性,这些属性是浮点数组,例如
private float[] _rawY;
public virtual float[] RawY
{
get
{
return _rawY;
}
set
{
_rawY = value;
}
}
这些数组最多可包含500个值。
我没想到Automapping会在阵列上运行,但无论如何都试过了, 起初取得了一些成功。每个数组都自动映射到BLOB (使用SQLite),这似乎是一个可行的解决方案。
第一个问题出现在我试图调用SaveOrUpdate时 包含数组的对象 - 我得到了“没有浮点数为浮点数[]” 例外。
所以我的下一个想法是将我的所有数组转换为IList,例如
public virtual IList<float> RawY { get; set; }
但现在我明白了:
NHibernate.MappingException: Association references unmapped class: System.Single
由于Automapping可以处理复杂对象的列表,因此它永远不会 发生在我身上,它将无法映射基本类型的列表。但 在做了一些谷歌搜索解决方案之后,情况似乎就是如此。 有些人似乎已经解决了问题,但是示例代码我 锯子需要比我现在更多的NHibernate知识 - 我 不明白。
问题:
1。如何通过自动映射实现此功能?
2。此外,为此应用程序使用数组或列表是否更好?
如果需要,我可以修改我的应用程序(虽然我更喜欢 列表)。
修改
我已经研究了Mapping Collection of Strings中的代码,我发现源代码中有测试代码设置了一个字符串的IList,例如。
public virtual IList<string> ListOfSimpleChildren { get; set; }
[Test]
public void CanSetAsElement()
{
new MappingTester<OneToManyTarget>()
.ForMapping(m => m.HasMany(x => x.ListOfSimpleChildren).Element("columnName"))
.Element("class/bag/element").Exists();
}
所以这一定是可以使用纯自动映射,但我没有运气得到任何工作,可能是因为我没有必要的知识手动映射NHibernate。
开始认为我将不得不破解这个(通过将浮点数组编码为单个字符串,或者创建一个包含单个浮点数的类,然后我将其聚合到我的列表中),除非有人能告诉我如何正确地做到这一点。
结束修改
这是我的CreateSessionFactory方法,如果这有助于制定一个 回复......
private static ISessionFactory CreateSessionFactory()
{
ISessionFactory sessionFactory = null;
const string autoMapExportDir = "AutoMapExport";
if( !Directory.Exists(autoMapExportDir) )
Directory.CreateDirectory(autoMapExportDir);
try
{
var autoPersistenceModel =
AutoMap.AssemblyOf<DlsAppOverlordExportRunData>()
.Where(t => t.Namespace == "DlsAppAutomapped")
.Conventions.Add( DefaultCascade.All() )
;
sessionFactory = Fluently.Configure()
.Database(SQLiteConfiguration.Standard
.UsingFile(DbFile)
.ShowSql()
)
.Mappings(m => m.AutoMappings.Add(autoPersistenceModel)
.ExportTo(autoMapExportDir)
)
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory()
;
}
catch (Exception e)
{
Debug.WriteLine(e);
}
return sessionFactory;
}
答案 0 :(得分:2)
自从我发布问题以来,Fluent NHibernate团队已经解决了这个问题。
现在,您可以自动执行C#值类型的IList(字符串,整数,浮点数等)。
请确保您拥有最新版本的FNH。
修改强>
我最近从FNH 1.0升级到FNH 1.3。
此版本还将自动化数组 - float [],int []等
似乎将它们映射为BLOB。我认为这比IList更有效,但没有做任何分析来确认。
答案 1 :(得分:1)
我可能会做一对多的关系,并将列表另一个表格......
但也许您需要重新考虑您的对象,是否还有一个可以组成RawPoint的RawX?这将创建一个包含3列(ParentID,X,Y)的表。
不连续性来自于希望将List映射到RDBMS中不会非常整齐地放入列中的值。表实际上是用于存储数据列表的方法。
这是使用像NHibernate这样的ORM的重点。在您的应用程序中手动执行所有查询和SQL组合时,添加表在维护和实现方面的成本很高。使用NHibernate,成本几乎为0,因此利用RDBMS的优势,让NHibernate抽象出丑陋。
我看到你映射数组的问题,首先尝试使用覆盖映射并查看它是否可行,然后你可以创建一个约定覆盖,如果你想让automap工作。
.Override<MyType>(map =>
{
map.HasMany(x => x.RawY).AsList();
})
不确定这是否有效,我需要为这些东西配置一个nHibernate测试设置。
答案 2 :(得分:1)
我最终获得了覆盖工作 - 请参阅代码清单的结尾。关键点是:
另外,事实证明(至少在1.0.0.594版本中)有一个非常大的问题与自动映射 - 映射类(例如DlsAppOverlordExportRunDataMap)不能与域类在同一个命名空间中(例如DlsAppOverlordExportRunData)!强>
否则,NHibernate将抛出“NHibernate.MappingException:(XmlDocument)(2,4):XML验证错误:......”,绝对没有迹象表明真正的问题是什么或在哪里
这可能是一个错误,可能会在Fluent NHibernate的更高版本中修复。
namespace DlsAppAutomapped
{
public class DlsAppOverlordExportRunData
{
public virtual int Id { get; set; }
// Note: List<float> needs overrides in order to be mapped by NHibernate.
// See class DlsAppOverlordExportRunDataMap.
public virtual IList<float> RawY { get; set; }
}
}
namespace FrontEnd
{
// NEW - SET UP THE OVERRIDES
// Must be in different namespace from DlsAppOverlordExportRunData!!!
public class DlsAppOverlordExportRunDataMap : IAutoMappingOverride<DlsAppOverlordExportRunData>
{
public void Override(AutoMapping<DlsAppOverlordExportRunData> mapping)
{
// Creates table called "RawY", with primary key
// "DlsAppOverlordExportRunData_Id", and numeric column "Value"
mapping.HasMany(x => x.RawY)
.Element("Value");
}
}
}
private static ISessionFactory CreateSessionFactory()
{
ISessionFactory sessionFactory = null;
const string autoMapExportDir = "AutoMapExport";
if( !Directory.Exists(autoMapExportDir) )
Directory.CreateDirectory(autoMapExportDir);
try
{
var autoPersistenceModel =
AutoMap.AssemblyOf<DlsAppOverlordExportRunData>()
.Where(t => t.Namespace == "DlsAppAutomapped")
// NEW - USE THE OVERRIDES
.UseOverridesFromAssemblyOf<DlsAppOverlordExportRunData>()
.Conventions.Add( DefaultCascade.All() )
;
sessionFactory = Fluently.Configure()
.Database(SQLiteConfiguration.Standard
.UsingFile(DbFile)
.ShowSql()
)
.Mappings(m => m.AutoMappings.Add(autoPersistenceModel)
.ExportTo(autoMapExportDir)
)
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory()
;
}
catch (Exception e)
{
Debug.WriteLine(e);
}
return sessionFactory;
}
答案 3 :(得分:0)
这里没有得到任何答案,或者在Fluent NHibernate邮件列表中没有得到任何答案,所以这就是我所做的。
它闻起来像一个可怕的黑客,但它的工作原理。 (它是否会扩展到大型数据集还有待观察)。
首先,我在一个类中包含了一个float属性(名为Value):
// Hack - need to embed simple types in a class before NHibernate
// will map them
public class MappableFloat
{
public virtual int Id { get; private set; }
public virtual float Value { get; set; }
}
然后我在其他类中声明需要浮点数列表的属性,例如
public virtual IList<MappableFloat> RawYMappable { get; set; }
NHibernate创建一个具有多个外键的数据库表,例如
create table "MappableFloat" (
Id integer,
Value NUMERIC,
DlsAppOverlordExportRunData_Id INTEGER,
DlsAppOverlordExportData_Id INTEGER,
primary key (Id)
)