1.0RC 版本中 Fluent Nhibernate Automapping 的问题

发布于 2024-08-03 04:37:16 字数 7751 浏览 9 评论 0原文

我是 NHibernate 的新手,在使 Automap 功能正常工作时遇到一些问题。这是我遇到的几个问题。

Fluent NHibernate 入门 wiki (http://wiki.fluentnhibernate.org/Getting_started) 定义了包含商店、产品和员工类别的示例以及这些类别的映射。我用 AutoMapping 替换了手动映射,并使用 Fluent NHibernate 生成架构。每件事都正确生成。但是,当应用程序尝试保存示例商店、产品和员工对象时,我收到错误“TransientObjectException 未处理:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例。类型:FluentExample.Entities.Employee ,实体:FluentExample.Entities.Employee”。

自动映射如下所示:

.Mappings(m=>
  m.AutoMappings.Add(
    AutoMap.AssemblyOf<FluentExample.Entities.Employee>(type => type.Namespace == "FluentExample.Entities")))

对象创建代码(直接来自 wiki)如下所示。我应该提到的是,使用手动流畅映射时,对象创建工作正常。

// create a couple of Stores each with some Products and Employees
var barginBasin = new Store { Name = "Bargin Basin" };
var superMart = new Store { Name = "SuperMart" };

var potatoes = new Product { Name = "Potatoes", Price = 3.60 };
var fish = new Product { Name = "Fish", Price = 4.49 };
var milk = new Product { Name = "Milk", Price = 0.79 };
var bread = new Product { Name = "Bread", Price = 1.29 };
var cheese = new Product { Name = "Cheese", Price = 2.10 };
var waffles = new Product { Name = "Waffles", Price = 2.41 };

var daisy = new Employee { FirstName = "Daisy", LastName = "Harrison" };
var jack = new Employee { FirstName = "Jack", LastName = "Torrance" };
var sue = new Employee { FirstName = "Sue", LastName = "Walkters" };
var bill = new Employee { FirstName = "Bill", LastName = "Taft" };
var joan = new Employee { FirstName = "Joan", LastName = "Pope" };

// add products to the stores, there's some crossover in the products in each
// store, because the store-product relationship is many-to-many
AddProductsToStore(barginBasin, potatoes, fish, milk, bread, cheese);
AddProductsToStore(superMart, bread, cheese, waffles);

// add employees to the stores, this relationship is a one-to-many, so one
// employee can only work at one store at a time                     
AddEmployeesToStore(barginBasin, daisy, jack, sue);
AddEmployeesToStore(superMart, bill, joan);

// save both stores, this saves everything else via cascading
session.SaveOrUpdate(barginBasin);
session.SaveOrUpdate(superMart);

transaction.Commit();

当尝试在我自己的一个类上使用 AutoMap 功能时,类是 创建,但由于某种原因,当我尝试实际创建时出现错误 插入一条记录。主要错误消息显示“AssertionFailure was 未处理:空值”。这是我的类的示例,config/ 映射、错误和创建表脚本。 (注:属性 类中的内容与 ASP.NET MVC 一起使用,与以下内容无关 NH.)

namespace Credit.Data.Entities
{
  [Serializable]
  public class EthnicityType
  {
    public EthnicityType()
    {
    }

    [DisplayName("Id")]
    [Required(ErrorMessage = "Id is required.")]
    public virtual Guid Id { get; private set; }

    [DisplayName("Title")]
    [Required(ErrorMessage = "Title is required.")]
    [StringLength(80, ErrorMessage = "Title must be less than 80 characters.")]
    public virtual string Title { get; set; }

    [DisplayName("Description")]
    [StringLength(255, ErrorMessage = "Description must be less than 255 characters.")]
    public virtual string Description { get; set; }

    [DisplayName("Is Active")]
    [Required(ErrorMessage = "Is Active is required.")]
    public virtual bool IsActive { get; set; }
  }
}

这是 Fluent NHibernate 配置。

private static ISessionFactory CreateSessionFactory()
{
  return Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2008
      .ConnectionString(c => c.FromConnectionStringWithKey ("CreditConnectionString"))
      .UseReflectionOptimizer()
      .AdoNetBatchSize(25)
      .DefaultSchema("dbo")
      .Cache(c => c
        .UseQueryCache()
        .ProviderClass<HashtableCacheProvider>())
      .ShowSql())
    .Mappings(m =>                    
      m.AutoMappings.Add(AutoMap.AssemblyOf<Credit.Data.Entities.EthnicityType>(type => type.Namespace == "Credit.Data.Entities")))
    .ExposeConfiguration(BuildSchema)
    .BuildSessionFactory();
}

还有错误。哎哟!

NHibernate.AssertionFailure was unhandled
  Message="null identifier"
  Source="NHibernate"
  StackTrace:
       at NHibernate.Engine.EntityKey..ctor(Object identifier, String
rootEntityName, String entityName, IType identifierType, Boolean
batchLoadable, ISessionFactoryImplementor factory, EntityMode
entityMode)
       at NHibernate.Engine.EntityKey..ctor(Object id,
IEntityPersister persister, EntityMode entityMode)
       at
NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate
(Object entity, EntityKey key, IEntityPersister persister, Boolean
useIdentityColumn, Object anything, IEventSource source, Boolean
requiresImmediateIdAccess)
       at
NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object
entity, Object id, IEntityPersister persister, Boolean
useIdentityColumn, Object anything, IEventSource source, Boolean
requiresImmediateIdAccess)
       at
NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId
(Object entity, String entityName, Object anything, IEventSource
source, Boolean requiresImmediateIdAccess)
       at
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId
(SaveOrUpdateEvent event)
       at
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient
(SaveOrUpdateEvent event)
       at
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate
(SaveOrUpdateEvent event)
       at
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate
(SaveOrUpdateEvent event)
       at NHibernate.Impl.SessionImpl.FireSaveOrUpdate
(SaveOrUpdateEvent event)
       at NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj)
       at FluentExample.Program.PopulateRecordTest(ISessionFactory
sessionFactory) in C:\Code\FluentExample\FluentExample\Program.cs:line
52
       at FluentExample.Program.BootstrapNH() in C:\Code\FluentExample
\FluentExample\Program.cs:line 32
       at FluentExample.Program.Main() in C:\Code\FluentExample
\FluentExample\Program.cs:line 24
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String
[] args)
       at
Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

还有表模式——只是为了好玩。

USE [Credit]
GO

/****** Object:  Table [dbo].[EthnicityType]    Script Date:
08/30/2009 04:59:31 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[EthnicityType](
  [ID] [uniqueidentifier] NOT NULL,
  [Title] [nvarchar](80) NOT NULL,
  [Description] [nvarchar](255) NULL,
  [IsActive] [bit] NOT NULL        
  CONSTRAINT [PK_EthnicityType_Title] PRIMARY KEY NONCLUSTERED
  (
    [ID] ASC
  )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY
    = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[EthnicityType] ADD  CONSTRAINT
  [DF_EthnicityType_ID]  DEFAULT (newid()) FOR [ID]
GO

ALTER TABLE [dbo].[EthnicityType] ADD  CONSTRAINT
  [DF_EthnicityType_IsActive]  DEFAULT ((1)) FOR [IsActive]
GO

我已经尝试了很多方法来让自动映射在我的环境中工作,但尚未完全成功。我尝试过的一些变化包括

  • 使用静态地图并允许 Fluent Nhibernate 重新创建我的表。
  • 将 Id 上的私有集更改为公共
  • 创建主键约定来尝试设置 Guid,以防出现问题并将其添加到我的映射中。

主键约定:

public class PrimaryKeyConvention : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        instance.GeneratedBy.GuidComb();
        //instance.GeneratedBy.Native();
    }
}

非常感谢任何建议或反馈。

I am new to NHibernate and am running into some issues getting the Automap functionality to work properly. Here are a couple of issues I am having.

The getting started wiki for Fluent NHibernate (http://wiki.fluentnhibernate.org/Getting_started) defines a sample with store, product, and employee classes--as well as the mapping for those classes. I replaced the manual mapping with AutoMapping and used Fluent NHibernate to generate the schema. Every thing generated properly. However, when the application attempted to save sample store, product, and employee objects, I received an error "TransientObjectException was Unhandled: object references an unsaved transient instance - save the transient instance before flushing. Type: FluentExample.Entities.Employee, Entity: FluentExample.Entities.Employee".

The automap looks like:

.Mappings(m=>
  m.AutoMappings.Add(
    AutoMap.AssemblyOf<FluentExample.Entities.Employee>(type => type.Namespace == "FluentExample.Entities")))

The object creation code (straight from the wiki) looks like the following. I should mention that the object creation works fine when using the manual fluent mapping.

// create a couple of Stores each with some Products and Employees
var barginBasin = new Store { Name = "Bargin Basin" };
var superMart = new Store { Name = "SuperMart" };

var potatoes = new Product { Name = "Potatoes", Price = 3.60 };
var fish = new Product { Name = "Fish", Price = 4.49 };
var milk = new Product { Name = "Milk", Price = 0.79 };
var bread = new Product { Name = "Bread", Price = 1.29 };
var cheese = new Product { Name = "Cheese", Price = 2.10 };
var waffles = new Product { Name = "Waffles", Price = 2.41 };

var daisy = new Employee { FirstName = "Daisy", LastName = "Harrison" };
var jack = new Employee { FirstName = "Jack", LastName = "Torrance" };
var sue = new Employee { FirstName = "Sue", LastName = "Walkters" };
var bill = new Employee { FirstName = "Bill", LastName = "Taft" };
var joan = new Employee { FirstName = "Joan", LastName = "Pope" };

// add products to the stores, there's some crossover in the products in each
// store, because the store-product relationship is many-to-many
AddProductsToStore(barginBasin, potatoes, fish, milk, bread, cheese);
AddProductsToStore(superMart, bread, cheese, waffles);

// add employees to the stores, this relationship is a one-to-many, so one
// employee can only work at one store at a time                     
AddEmployeesToStore(barginBasin, daisy, jack, sue);
AddEmployeesToStore(superMart, bill, joan);

// save both stores, this saves everything else via cascading
session.SaveOrUpdate(barginBasin);
session.SaveOrUpdate(superMart);

transaction.Commit();

When attempting to use the AutoMap functionality on one of my own classes, a class is
created, but for some reason I get errors when I attempt to actually
insert a record. The main error message says "AssertionFailure was
unhandled: null value".
Here is a sample of my class, the config/
mapping, the error, and the create table script. (Note: The attributes
in the class are for use with ASP.NET MVC and have nothing to do with
NH.)

namespace Credit.Data.Entities
{
  [Serializable]
  public class EthnicityType
  {
    public EthnicityType()
    {
    }

    [DisplayName("Id")]
    [Required(ErrorMessage = "Id is required.")]
    public virtual Guid Id { get; private set; }

    [DisplayName("Title")]
    [Required(ErrorMessage = "Title is required.")]
    [StringLength(80, ErrorMessage = "Title must be less than 80 characters.")]
    public virtual string Title { get; set; }

    [DisplayName("Description")]
    [StringLength(255, ErrorMessage = "Description must be less than 255 characters.")]
    public virtual string Description { get; set; }

    [DisplayName("Is Active")]
    [Required(ErrorMessage = "Is Active is required.")]
    public virtual bool IsActive { get; set; }
  }
}

Here is the Fluent NHibernate configuration.

private static ISessionFactory CreateSessionFactory()
{
  return Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2008
      .ConnectionString(c => c.FromConnectionStringWithKey ("CreditConnectionString"))
      .UseReflectionOptimizer()
      .AdoNetBatchSize(25)
      .DefaultSchema("dbo")
      .Cache(c => c
        .UseQueryCache()
        .ProviderClass<HashtableCacheProvider>())
      .ShowSql())
    .Mappings(m =>                    
      m.AutoMappings.Add(AutoMap.AssemblyOf<Credit.Data.Entities.EthnicityType>(type => type.Namespace == "Credit.Data.Entities")))
    .ExposeConfiguration(BuildSchema)
    .BuildSessionFactory();
}

And the error. Yuk!

NHibernate.AssertionFailure was unhandled
  Message="null identifier"
  Source="NHibernate"
  StackTrace:
       at NHibernate.Engine.EntityKey..ctor(Object identifier, String
rootEntityName, String entityName, IType identifierType, Boolean
batchLoadable, ISessionFactoryImplementor factory, EntityMode
entityMode)
       at NHibernate.Engine.EntityKey..ctor(Object id,
IEntityPersister persister, EntityMode entityMode)
       at
NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate
(Object entity, EntityKey key, IEntityPersister persister, Boolean
useIdentityColumn, Object anything, IEventSource source, Boolean
requiresImmediateIdAccess)
       at
NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object
entity, Object id, IEntityPersister persister, Boolean
useIdentityColumn, Object anything, IEventSource source, Boolean
requiresImmediateIdAccess)
       at
NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId
(Object entity, String entityName, Object anything, IEventSource
source, Boolean requiresImmediateIdAccess)
       at
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId
(SaveOrUpdateEvent event)
       at
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient
(SaveOrUpdateEvent event)
       at
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate
(SaveOrUpdateEvent event)
       at
NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate
(SaveOrUpdateEvent event)
       at NHibernate.Impl.SessionImpl.FireSaveOrUpdate
(SaveOrUpdateEvent event)
       at NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj)
       at FluentExample.Program.PopulateRecordTest(ISessionFactory
sessionFactory) in C:\Code\FluentExample\FluentExample\Program.cs:line
52
       at FluentExample.Program.BootstrapNH() in C:\Code\FluentExample
\FluentExample\Program.cs:line 32
       at FluentExample.Program.Main() in C:\Code\FluentExample
\FluentExample\Program.cs:line 24
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String
[] args)
       at
Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

And the table schema--just for kicks.

USE [Credit]
GO

/****** Object:  Table [dbo].[EthnicityType]    Script Date:
08/30/2009 04:59:31 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[EthnicityType](
  [ID] [uniqueidentifier] NOT NULL,
  [Title] [nvarchar](80) NOT NULL,
  [Description] [nvarchar](255) NULL,
  [IsActive] [bit] NOT NULL        
  CONSTRAINT [PK_EthnicityType_Title] PRIMARY KEY NONCLUSTERED
  (
    [ID] ASC
  )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY
    = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[EthnicityType] ADD  CONSTRAINT
  [DF_EthnicityType_ID]  DEFAULT (newid()) FOR [ID]
GO

ALTER TABLE [dbo].[EthnicityType] ADD  CONSTRAINT
  [DF_EthnicityType_IsActive]  DEFAULT ((1)) FOR [IsActive]
GO

I've tried a number of things to get automapping working in my environment but just have not yet been fully successful. Some variations I have tried include

  • Using a static map and allowing Fluent Nhibernate to recreate my table.
  • Changing the private set on Id to public
  • Creating a primarykeyconvention to try and set the Guid in case that was the issue and adding this to my mapping.

Primary Key Convention:

public class PrimaryKeyConvention : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        instance.GeneratedBy.GuidComb();
        //instance.GeneratedBy.Native();
    }
}

Any advice or feedback is very much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

青朷 2024-08-10 04:37:16

Fluent NHibernate 示例实体位于 Examples.FirstProject.Entities 命名空间中,而您将 AutoMap 限制为 FluentExample.Entities(在 type => type 中) .命名空间==“FluentExample.Entities”)。

第一条错误消息指出“引用未保存的瞬态实例 [...]FluentExample.Entities.Employee”,

您应该更新 AutoMap 代码以指向正确的接口。如果多个接口中有类,则可以修改条件以包含“或”。

The Fluent NHibernate example entities are in the Examples.FirstProject.Entities namespace, while you're limiting the AutoMap to FluentExample.Entities (in type => type.Namespace == "FluentExample.Entities").

The first error message points to that by stating "references an unsaved transient instance [...] FluentExample.Entities.Employee"

You should update the AutoMap code to point to the correct interface. If you have classes in multiple interfaces, you can modify the criteria to include an or.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文