Проблемы с Fluent Nhibernate Automapping в версии 1.0RC

Я новичок в NHibernate, и у меня возникают проблемы с правильной работой функции Automap. Вот пара проблем, которые у меня возникают.

Вики по началу работы с Fluent NHibernate (http://wiki.fluentnhibernate.org/Getting_started определяет образец с классами магазина, продукта и сотрудников, а также сопоставление этих классов. Я заменил ручное сопоставление на AutoMapping и использовал Fluent NHibernate для создания схемы. Все создано правильно. Однако, когда приложение попыталось сохранить образцы объектов магазина, продукта и сотрудника, я получил сообщение об ошибке «TransientObjectException было необработано: объект ссылается на несохраненный временный экземпляр - сохраните временный экземпляр перед сбросом». Тип: FluentExample.Entities.Employee , Entity: FluentExample.Entities.Employee ".

Автокарта выглядит так:

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

Код создания объекта (прямо из вики) выглядит следующим образом. Следует отметить, что создание объекта отлично работает при использовании ручного плавного сопоставления.

// 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 была необработана: нулевое значение». Вот пример моего класса, конфигурации / сопоставления, ошибки и сценария создания таблицы. (Примечание: атрибуты в классе предназначены для использования с 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 воссоздать мою таблицу.
  • Изменение частного набора идентификатора на общедоступный
  • Создание соглашения primarykey, чтобы попытаться установить Guid на случай, если это была проблема, и добавить его в мое сопоставление.

Соглашение о первичном ключе:

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

Мы очень ценим любые советы или отзывы.


person Community    schedule 30.08.2009    source источник


Ответы (1)


Примеры сущностей Fluent NHibernate находятся в пространстве имен Examples.FirstProject.Entities, в то время как вы ограничиваете AutoMap до FluentExample.Entitiestype => type.Namespace == "FluentExample.Entities").

Первое сообщение об ошибке указывает на это, заявляя "ссылается на несохраненный временный экземпляр [...] FluentExample.Entities.Employee"

Вам следует обновить код AutoMap, чтобы он указывал на правильный интерфейс. Если у вас есть классы в нескольких интерфейсах, вы можете изменить критерии, чтобы включить или.

person James Gregory    schedule 31.08.2009