私はクラスTaskを持っていて、そこからいくつかのコードをロードして実行するdllというTaskLibraryというプロパティを持っています。したがって、どのタスクにも1つのライブラリがありますが、どのライブラリも多くのタスクを持つことができます。私の問題は、タスクのライブラリプロパティがnullでないことを確認するための私のテストが失敗していることです(私のテストになるかもしれません)。NHibernateとNUnitを使って1対多のrealtionshipをテストするのに役立ちます
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のマッピングは次のようになります。:MSSQL2000データベース内
[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);
}
}
そして、タスクテーブル:
<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>
私のテストクラスは次のようになります私のクラスには、効果的に、このですこれはです:
CREATE TABLE [dbo].[Tasks](
[TaskId] [int] IDENTITY(1,1) NOT NULL,
[TaskLibrary] [int] NOT NULL,
[Status] [int] NOT NULL,
[Locked] [int] NOT NULL
)
あなたがまだ私と一緒にいるなら...
私のタスククラスからは、ライブラリプロパティのTaskLibraryクラスのインスタンスが必要です。また、私がライブラリ自体で作業している場合、そのライブラリを使用しているすべてのタスクの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はを使用したのは初めてなので、私はまだ学んでいます。私は本当に基礎の基礎を身につけたいと思っています。そのときまで私はここで立ち往生しています。助け、提案、資料の読んだり(私はthis question'sの提案や他のものすべてを読んだことがあります)
EDIT:
"参加" =フェッチ変更した後、私はTaskクラスから必要な機能を取得しています。
[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");
}
しかし、アサーションは(私が行ったすべての変更を反映するために、上記のコードを更新しました)このエラーで失敗します。しかし、私はTaskLibraryクラスのタスクのプロパティのための別のテストを追加しました:
TestCase 'DistPollAutoTasksShared.Tests.TaskLibraryRepositoryFixture.CanGetTasksByLibrary'
failed:
Cannot get IEnumerable<Tasks> from TaskLibrary
Expected: True
But was: False
これは、セッションが開いている間に遅延ロードしかできないためです。これは、再帰的に発行されているたくさんのselect文で終わる可能性があるので、TaskLibrary.Tasksを熱心に読み込むことは望ましくありません。 @ドットジョー、右。 – dotjoe
だから私はlazy = "true"に設定しましたが、それでも例外はスローされます。だから、私は怠惰な読み込みがどのように働くのか理解してはいけません。 – scottm
基本的に遅延読み込みは、(仮想プロパティを使用して)pocoを拡張することによって機能し、プロパティの1つにアクセスすると、ロードされたセッションを使用しようとします。セッションが終了した場合、エラーが発生します。したがって、あなたの場合、タスクはタスクにアクセスしようとする前に開いて閉じています。 – dotjoe