使用 fluent nhibernate 排除私有字段
Excluding private fields with fluent nhibernate
我希望使用 NHibernate 和 sqlite 数据库以尽可能少的痛苦将数据库改造为现有代码库。我想通过使用 AutoMapper 来映射我用 [DatabaseField] 自定义属性标记的字段,以用于从自定义 DatabaseObject class 继承的任何对象。任何标有 [Cascade] 自定义属性的内容都将被级联。我目前在测试项目中有以下代码:
要映射的实体:
class Scan : DatabaseObject
{
[DatabaseField]
public virtual string Name { get; set; }
[DatabaseField]
public virtual DateTime ScanDate { get; set; }
[DatabaseField]
[Cascade]
public virtual Scanner Scanner { get; set; }
public DateTime ManufactureDate { get; set; }
}
class Scanner : DatabaseObject
{
[DatabaseField]
public virtual string Name { get; set; }
}
会话设置:
ProjectConfiguration pcfg = new ProjectConfiguration();
var sessionFactory = Fluently.Configure()
.Database(SQLiteConfiguration.Standard.UsingFile("theTestScannerDatabase.sqlite"))
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Scan>(pcfg)
.Override<Scan>(x => x.IgnoreProperty(y => y.ManufactureDate)).Conventions.Setup(x => x.AddFromAssemblyOf<Scan>())))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
return sessionFactory.OpenSession();
项目配置对象
public class ProjectConfiguration : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Type type)
{
return type.BaseType == typeof(DatabaseObject);
}
public override bool ShouldMap(Member member)
{
return member.MemberInfo.GetCustomAttributes().Contains(new DatabaseField());
}
}
问题出在自动映射器试图映射的 "ManufactureDate" 字段上,但由于它不是虚拟的 属性 而感到不安,私有属性也会发生类似的事情。我不想将每个 属性 对象都映射到数据库。我认为 ShouldMap 覆盖中的标签和内容应该处理这个问题。
异常:
InvalidProxyTypeException: The following types may not be used as proxies:
SQLiteTestingApp.Scan: method get_ManufactureDate should be 'public/protected virtual' or 'protected internal virtual'
SQLiteTestingApp.Scan: method set_ManufactureDate should be 'public/protected virtual' or 'protected internal virtual'
郑重声明,如果我删除此字段,其他所有内容都将完全符合我的要求。
我已经阅读了有关 Override 和 OverrideAll 方法的信息,我曾尝试使用这些方法来显式排除这些字段,但它似乎没有任何效果。我在上面的代码片段中留下了这种尝试的示例。
所以我想我有两个问题:
- 我怎样才能告诉自动映射器忽略任何我没有用我的属性标记的东西?
- 如果这不可能,那么在不为我要映射的每个对象创建映射 class 的情况下将现有对象映射到数据库的最简单方法是什么?
提前致谢
查看 ignoring properties 的文档。
您可以使用IgnoreProperty
方法。
.Override<Scan>(map =>
{
map.IgnoreProperty(x => x.ManufactureDate);
});
实体中的所有 properties/methods 也需要是虚拟的或根据 persistent classes 的文档实现接口。
A central feature of NHibernate, proxies, depends upon the persistent
class being non-sealed and all its public methods, properties and
events declared as virtual. Another possibility is for the class to
implement an interface that declares all public members.
我希望使用 NHibernate 和 sqlite 数据库以尽可能少的痛苦将数据库改造为现有代码库。我想通过使用 AutoMapper 来映射我用 [DatabaseField] 自定义属性标记的字段,以用于从自定义 DatabaseObject class 继承的任何对象。任何标有 [Cascade] 自定义属性的内容都将被级联。我目前在测试项目中有以下代码:
要映射的实体:
class Scan : DatabaseObject
{
[DatabaseField]
public virtual string Name { get; set; }
[DatabaseField]
public virtual DateTime ScanDate { get; set; }
[DatabaseField]
[Cascade]
public virtual Scanner Scanner { get; set; }
public DateTime ManufactureDate { get; set; }
}
class Scanner : DatabaseObject
{
[DatabaseField]
public virtual string Name { get; set; }
}
会话设置:
ProjectConfiguration pcfg = new ProjectConfiguration();
var sessionFactory = Fluently.Configure()
.Database(SQLiteConfiguration.Standard.UsingFile("theTestScannerDatabase.sqlite"))
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Scan>(pcfg)
.Override<Scan>(x => x.IgnoreProperty(y => y.ManufactureDate)).Conventions.Setup(x => x.AddFromAssemblyOf<Scan>())))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
return sessionFactory.OpenSession();
项目配置对象
public class ProjectConfiguration : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Type type)
{
return type.BaseType == typeof(DatabaseObject);
}
public override bool ShouldMap(Member member)
{
return member.MemberInfo.GetCustomAttributes().Contains(new DatabaseField());
}
}
问题出在自动映射器试图映射的 "ManufactureDate" 字段上,但由于它不是虚拟的 属性 而感到不安,私有属性也会发生类似的事情。我不想将每个 属性 对象都映射到数据库。我认为 ShouldMap 覆盖中的标签和内容应该处理这个问题。
异常:
InvalidProxyTypeException: The following types may not be used as proxies:
SQLiteTestingApp.Scan: method get_ManufactureDate should be 'public/protected virtual' or 'protected internal virtual'
SQLiteTestingApp.Scan: method set_ManufactureDate should be 'public/protected virtual' or 'protected internal virtual'
郑重声明,如果我删除此字段,其他所有内容都将完全符合我的要求。
我已经阅读了有关 Override 和 OverrideAll 方法的信息,我曾尝试使用这些方法来显式排除这些字段,但它似乎没有任何效果。我在上面的代码片段中留下了这种尝试的示例。
所以我想我有两个问题:
- 我怎样才能告诉自动映射器忽略任何我没有用我的属性标记的东西?
- 如果这不可能,那么在不为我要映射的每个对象创建映射 class 的情况下将现有对象映射到数据库的最简单方法是什么?
提前致谢
查看 ignoring properties 的文档。
您可以使用IgnoreProperty
方法。
.Override<Scan>(map =>
{
map.IgnoreProperty(x => x.ManufactureDate);
});
实体中的所有 properties/methods 也需要是虚拟的或根据 persistent classes 的文档实现接口。
A central feature of NHibernate, proxies, depends upon the persistent class being non-sealed and all its public methods, properties and events declared as virtual. Another possibility is for the class to implement an interface that declares all public members.