我遇到了Fluent NHibernate的问题,其中自动化没有在我的Web项目DLL中获取权限。通常我将所有实体存储在一个单独的程序集中,这一直都有效。但是,这个项目相当小,所以我试图将它全部保存在一个项目中。但是,当我调用AutoMap.AssemblyOf<MyEntityType>()
时,不会创建映射。我想知道这是否是因为该实体存在于从临时ASP.NET文件文件夹加载的Web项目程序集中,而不是项目所在的实际文件夹。是权限问题还是什么?我不知道从哪里开始调试......
示例实体:
namespace MyProject.Entities
{
public class Letter : EntityBase
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string Country { get; set; }
public string Interest { get; set; }
public string Section1 { get; set; }
public string Section2 { get; set; }
public string Section3 { get; set; }
public string LetterText { get; set; }
public int StepNumber { get; set; }
}
}
相关的推特代码:
private static ISessionFactory GetSessionFactory()
{
var database = MsSqlConfiguration.MsSql2005
.ConnectionString(Configuration.ConnectionString)
.DefaultSchema(DEFAULT_SCHEMA)
.AdoNetBatchSize(BATCH_SIZE);
var mappings = AutoMap.AssemblyOf<Letter>()
.Where(x => x.GetType() == typeof(Letter))
.Conventions.Add
(
ConventionBuilder.Id.Always(x =>
x.GeneratedBy.HiLo(HILO_TABLE, HILO_COLUMN, HILO_MAX_LO)),
ConventionBuilder.HasMany.Always(x => x.Cascade.AllDeleteOrphan()),
Table.Is(o => Inflector.Pluralize(o.EntityType.Name)),
PrimaryKey.Name.Is(o => "Id"),
ForeignKey.EndsWith("Id"),
DefaultLazy.Never(),
DefaultCascade.All()
);
// ...
我更改了Where子句以查找特定类型而不是命名空间,但这也不起作用。映射对象仍然是空的。
此外,EntityBase类是一个空类,但是对于一个由所有实体继承的属性“Id”。
编辑:我将实体移动到他们自己的程序集中并且仍然遇到问题,因此它与Web项目程序集的位置无关。我还是很遗憾。 :(
答案 0 :(得分:2)
我发现了问题。我从EntityBase继承但没有IgnoreBase调用。我假设因为EntityBase不在命名空间中我有资格获得我不需要它的映射,但显然,如果你没有明确地忽略基类,即使它是另一个命名空间,映射也会失败。
新的引导代码如下所示:
private static ISessionFactory GetSessionFactory()
{
var database = MsSqlConfiguration.MsSql2005
.ConnectionString(Configuration.ConnectionString)
.DefaultSchema(DEFAULT_SCHEMA)
.AdoNetBatchSize(BATCH_SIZE);
var mappings = AutoMap.AssemblyOf<Letter>()
.Where(x => x.GetType() == typeof(Letter))
.IgnoreBase<EntityBase>()
.Conventions.Add
(
ConventionBuilder.Id.Always(x =>
x.GeneratedBy.HiLo(HILO_TABLE, HILO_COLUMN, HILO_MAX_LO)),
ConventionBuilder.HasMany.Always(x => x.Cascade.AllDeleteOrphan()),
Table.Is(o => Inflector.Pluralize(o.EntityType.Name)),
PrimaryKey.Name.Is(o => "Id"),
ForeignKey.EndsWith("Id"),
DefaultLazy.Never(),
DefaultCascade.All()
);
// ...
答案 1 :(得分:0)
试试这个,让我知道会发生什么:
var config = Fluently.Configure()
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Letter>()
.Where(n => n.Name == "Letter"))
.ExportTo(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) + "/mappings"))
.BuildConfiguration();
var factory = config.BuildSessionFactory();
我完全没有通知的猜测是你没有调用BuildConfiguration()
,所以NHibernate没有打扰创建映射。
答案 2 :(得分:0)
我创建了一个新的 ASP.NET MVC 应用程序并添加了这两个类和这个配置:
public abstract class Entity
{
public int Id { get; set; }
}
public class Letter
{
public string Name { get; set; }
}
// this is in Global.asax
protected void Application_Start()
{
Fluently.Configure()
.Database(SQLiteConfiguration.Standard.InMemory())
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Entity>()
.Where(t => t.IsSubclassOf(typeof (Entity))))
.ExportTo(*the desktop*))
.BuildConfiguration();
}
此代码能够成功导出映射。
修改强>
刚看到你的答案。不确定为什么要IgnoreBase()
解决问题。这应该只确定如何为子类策略映射基类。哦,好吧。
答案 3 :(得分:0)
我发现域类需要在一个单独的程序集中,而不是构建ISessionFactory的代码。将域对象移动到单独的程序集后,一切都应该正常工作。
出于好奇,我尝试了Conventions.Add从上面的想法,它永远不会工作。意思是,我可以使用这样的域类:
public class Person
{
public virtual int Id { get; private set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
}
使用如下所示的AutoMapping例程:
public NHibernate.ISessionFactory Create()
{
var persistenceModel =
AutoMap
.AssemblyOf<Person>();
var ret =
Fluently
.Configure()
.Database(MsSqlCeConfiguration.Standard.ShowSql().FormatSql().ConnectionString(ex => ex.FromConnectionStringWithKey("PersonSqlCe")))
.Mappings(x => x.AutoMappings.Add(persistenceModel))
.ExposeConfiguration(config =>
{
new SchemaExport(config).Create(true, true);
// DOC: workaround for identity column failures in SQLCE
config.SetProperty("connection.release_mode", "on_close");
})
.BuildSessionFactory();
return ret;
}
一切正常。但是,当我将我的域类更改为如下所示:
public class Person
{
public virtual int BAD { get; private set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
}
并更改我的AutoMapping例程以符合新的PrimaryKey属性名称期望,例如下面的代码:
public NHibernate.ISessionFactory Create()
{
var persistenceModel =
AutoMap
.AssemblyOf<Person>();
persistenceModel.Conventions.Add(PrimaryKey.Name.Is(x => "BAD"));
var ret =
Fluently
.Configure()
.Database(MsSqlCeConfiguration.Standard.ShowSql().FormatSql().ConnectionString(ex => ex.FromConnectionStringWithKey("PersonSqlCe")))
.Mappings(x => x.AutoMappings.Add(persistenceModel))
.ExposeConfiguration(config =>
{
new SchemaExport(config).Create(true, true);
// DOC: workaround for identity column failures in SQLCE
config.SetProperty("connection.release_mode", "on_close");
})
.BuildSessionFactory();
return ret;
}
...我收到如下错误:
----> FluentNHibernate.Visitors.ValidationException : The entity 'Person' doesn't have an Id mapped. Use the Id method to map your identity property. For example: Id(x => x.Id).
at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory()
SampleImplementation.cs(28,0): at NHQS.Tests.PersonSampleSessionFactoryCreator.Create()
SessionFactoryTests.cs(16,0): at
是什么给出的?似乎会议方法没有布线?