Так у меня есть класс:NHibernate Ленивого Loaded Свойства с составным ключом Issue (Работает в SQLite не в SQL Server 2008)
public class objWalkdown {
private objWalkdown_ID _walkdownId = new objWalkdown_ID();
public virtual objWalkdown_ID Id {
get { return _walkdownId; }
set { _walkdownId = value; }
}
public virtual String facility {
get { return _walkdownId.facility; }
set { _walkdownId.facility = value; }
}
public virtual String walkdown {
get { return _walkdownId.walkdown; }
set { _walkdownId.walkdown = value; }
}
public virtual String activity {
get { return _walkdownId.activity; }
set { _walkdownId.activity = value; }
}
public virtual Boolean complete { get; set; }
public virtual Byte[] filedata { get; set; }
}
Это использует композитные установки ID в другом классе:
[Serializable]
public class objWalkdown_ID {
public virtual String facility { get; set; }
public virtual String walkdown { get; set; }
public virtual String activity { get; set; }
}
Из моего исследования это сериализованная Составной ключ необходим для того, чтобы облегчить отложенную загрузку на имущество (т.е. обычный составной ключ, установка не будет работать), показанный здесь, мой свободный NNibernate отображение класса:
public class objWalkdown_ORM : ClassMap<objWalkdown> {
public objWalkdown_ORM() {
Id(x => x.Id);
Map(x => x.facility);
Map(x => x.walkdown);
Map(x => x.activity);
Map(x => x.complete);
Map(x => x.filedata)
.CustomType("BinaryBlob")
.LazyLoad();
Table("tbPDFs");
}
}
И этот 100% работает, когда NHibernate подключен к моей тестовой базе данных SQLite, но при переходе на SQL Server 2008 все пошло немного. Единственным реальным изменением БД является тип SQLite BINARY
для типа SQL Server 2008 VARBINARY(MAX)
. Однако при ленивой загрузке все работает с обеих сторон, только когда в моей собственности помечен ленивый вариант загрузки, что все начинает ломаться. Вот пример того, как я получить доступ к данным:
public Stream getWalkdown(String Facility, String Walkdown, String Activity) {
//Use NHibernate Session setup "Per-Request"
ISession session = (ISession)HttpContext.Current.Items["NHSession"];
//Build composite Id
objWalkdown_ID id = new objWalkdown_ID() { facility = Facility, walkdown = Walkdown, activity = Activity };
//Get the entity
objWalkdown walkdown = session.Get<objWalkdown>(id);
//Lazy Load File Data and return a memory stream
return new MemoryStream(walkdown.filedata);
}
Пожалуйста, сосредоточить внимание на ленивой загрузке части и не спрашивай меня, чтобы не использовать его, цель этого вопроса заключается в определении точно, что это неправильно с ленивой загрузкой. Как я уже сказал, использование SQLite это 100%. Он также будет работать как в SQLite, так и в SQL Server 2008, если потерянная загрузка будет удалена, поэтому я не думаю, что это фактические типы данных на задней панели.
Специфическая ошибка, с которой я сталкиваюсь при проверке объекта walkdown (до ленивой загрузки), - «System.InvalidOperationException - Неверная попытка прочитать, когда данных нет». Однако определенно присутствуют данные. Поэтому я думаю, что это проблема с прокси-сервером NHibernate.
Вот трассировки стека:
at System.Data.SqlClient.SqlDataReader.ReadColumnHeader(Int32 i)
at System.Data.SqlClient.SqlDataReader.IsDBNull(Int32 i)
at NHibernate.Driver.NHybridDataReader.IsDBNull(Int32 i)
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name)
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String[] names, ISessionImplementor session, Object owner)
at NHibernate.Persister.Entity.AbstractEntityPersister.InitializeLazyPropertiesFromDatastore(String fieldName, Object entity, ISessionImplementor session, Object id, EntityEntry entry)
at NHibernate.Persister.Entity.AbstractEntityPersister.InitializeLazyProperty(String fieldName, Object entity, ISessionImplementor session)
at NHibernate.Intercept.AbstractFieldInterceptor.InitializeField(String fieldName, Object target)
at NHibernate.Intercept.AbstractFieldInterceptor.Intercept(Object target, String fieldName, Object value)
at NHibernate.Intercept.DefaultDynamicLazyFieldInterceptor.Intercept(InvocationInfo info)
at objWalkdownProxy.get_filedata()
Я надеюсь, что кто-то может дать мне несколько советов на правильное решение. У меня уже есть работа, но она включает HQL и с нетерпением загружает объект, когда мне нужны данные файла, чего я не хочу делать.