У меня есть класс Task, и у него есть свойство TaskLibrary, из которого dll будет загружать и запускать некоторый код. Итак, любая задача имеет одну библиотеку, но любая библиотека может иметь много задач. Моя проблема в том, что мой тест для проверки того, что свойство Library задачи не равно null, не проходит (поэтому это может быть просто мой тест). Мои занятия по сути такие:
public class Task
{
public virtual int TaskId {get;set;}
public virtual string Locked {get;set;}
public virtual int Status {get;set;}
public virtual TaskLibrary Library {get;set;}
}
public class TaskLibrary
{
public virtual int LibraryId {get;set}
public virtual string Name {get;set;}
public virtual string Description {get;set;}
public virtual byte[] Dll {get;set}
public virtual IEnumerable<Task> Tasks {get;set;}
}
Мои сопоставления NHibernate выглядят так:
<class name="Task">
<id name="Id" column="TaskId" type="Int32" unsaved-value="-1">
<generator class="identity"/>
</id>
<property name="Locked" column="Locked"/>
<property name="Status" column="Status"/>
<many-to-one name="Library" class="TaskLibrary" fetch="join"/>
</class>
<class name="TaskLibrary">
<id name="Id" column="LibraryId">
<generator class="identity"/>
</id>
<property name="Name"/>
<property name="Description"/>
<property name="Dll"/>
<set name="Tasks" lazy="true">
<key column="LibraryId"/>
<one-to-many class="Task"/>
</set>
</class>
Мой тестовый класс выглядит так:
[TestFixture]
public class TaskRepositoryFixture
{
private ISessionFactory _sessionFactory;
private Configuration _configuration;
private readonly Task[] _tasks = new[]
{
new Task {Id = 1, Status = 1, Locked = 0, Library = new TaskLibrary { Id =1, Description = "Test Library", Name = "Tast.dll", Type = "RunnableTask", Dll = Encoding.ASCII.GetBytes("test binary data")}},
new Task {Id = 2, Status = 1, Locked = 0, Library = new TaskLibrary { Id =1, Description = "Test Library", Name = "Tast.dll", Type = "RunnableTask", Dll = Encoding.ASCII.GetBytes("test binary data")}},
new Task {Id = 3, Status = 1, Locked = 0, Library = new TaskLibrary { Id =2, Description = "Test Library 2", Name = "Tast2.dll", Type = "RunnableTask", Dll = Encoding.ASCII.GetBytes("test binary data")}},
new Task {Id = 4, Status = 1, Locked = 0, Library = new TaskLibrary { Id =2, Description = "Test Library 2", Name = "Tast2.dll", Type = "RunnableTask", Dll = Encoding.ASCII.GetBytes("test binary data")}},
new Task {Id = 5, Status = 1, Locked = 0, Library = new TaskLibrary { Id =3, Description = "Test Library 3", Name = "Tast3.dll", Type = "RunnableTask", Dll = Encoding.ASCII.GetBytes("test binary data")}},
};
private readonly TaskLibrary[] _libraries = new[]
{
new TaskLibrary { Id =1, Description = "Test Library", Name = "Tast.dll", Type = "RunnableTask", BinaryDll = Encoding.ASCII.GetBytes("test binary data")},
new TaskLibrary { Id =2, Description = "Test Library 2", Name = "Tast2.dll", Type = "RunnableTask", BinaryDll = Encoding.ASCII.GetBytes("test binary data")},
new TaskLibrary { Id =3, Description = "Test Library 3", Name = "Tast3.dll", Type = "RunnableTask", BinaryDll = Encoding.ASCII.GetBytes("test binary data")}
};
private void CreateInitialData()
{
using (ISession session = _sessionFactory.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
foreach (var lib in _libraries)
session.Save(lib);
foreach (var task in _tasks)
session.Save(task);
transaction.Commit();
}
}
[TestFixtureSetUp]
public void TestFixtureSetUp()
{
_configuration = new Configuration();
_configuration.Configure();
_configuration.AddAssembly("DistPollAutoTasksShared");
_sessionFactory = _configuration.BuildSessionFactory();
}
[SetUp]
public void SetupContext()
{
new SchemaExport(_configuration).Execute(false, true, false, false);
CreateInitialData();
}
[Test]
public void CanGetLibraryFromTask()
{
ITaskRepository repository = new TaskRepository();
var fromDb = repository.GetById(_tasks[0].Id);
Assert.IsNotNull(fromDb.Library);
Assert.IsNotNull(fromDb.Library.Dll);
}
}
И таблица задач в базе данных MSSQL2000 выглядит так:
CREATE TABLE [dbo].[Tasks](
[TaskId] [int] IDENTITY(1,1) NOT NULL,
[TaskLibrary] [int] NOT NULL,
[Status] [int] NOT NULL,
[Locked] [int] NOT NULL
)
Если ты все еще со мной ...
Из моего класса Task я просто хочу экземпляр класса TaskLibrary для свойства Library. Кроме того, если я работаю с самими библиотеками, я хочу иметь возможность лениво извлекать IEnumerable из всех задач, использующих эту библиотеку. Однако, когда я запускаю тест, я получаю эту ошибку:
TestCase 'DistPollAutoTasksShared.Tests.TaskRepositoryFixture.CanGetLibraryFromTask'
failed: NHibernate.LazyInitializationException : Could not initialize proxy - no Session.
at NHibernate.Proxy.AbstractLazyInitializer.Initialize()
at NHibernate.Proxy.AbstractLazyInitializer.GetImplementation()
at NHibernate.Proxy.Poco.Castle.CastleLazyInitializer.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at TaskLibraryProxy2bd44073e90f47298039abfbfda11492.get_Dll()
Я впервые использую NHibernate, так что я все еще учусь. Я действительно хочу получить хорошую основу основ, поэтому я застрял здесь до тех пор. Буду признателен за любую помощь, предложения, материалы для чтения (я прочитал все предложения этого вопроса и некоторые другие) и будет признателен.
EDIT:
После изменения fetch = "join" я получаю нужные мне функции из класса Task. Однако я добавил еще один тест для свойства Tasks класса TaskLibrary:
[Test]
public void CanGetTasksByLibrary()
{
ITaskLibraryRepository repository = new TaskLibraryRepository();
var fromDb = repository.GetById(_libraries[0].Id).Tasks;
Assert.IsNotNull(fromDb);
Assert.True(fromDb.Count() == 2, "Cannot get IEnumerable<Task> from TaskLibrary");
}
Но утверждение не удается с этой ошибкой (я обновил код выше, чтобы отразить любые изменения, которые я сделал):
TestCase 'DistPollAutoTasksShared.Tests.TaskLibraryRepositoryFixture.CanGetTasksByLibrary'
failed:
Cannot get IEnumerable<Tasks> from TaskLibrary
Expected: True
But was: False