1

多対多のクラスをテストすると、エラーが発生します。

System.ApplicationException:実際のカウントが期待されるカウントと等しくありません。

エンティティ:

    public interface IEntity
    {
        int Id { get; set; }
    }

    public abstract class Entity : IEntity
    {
        public virtual int Id { get; set; }

        public virtual bool IsPersistent
        {
            get { return isPersistentObject(); }
        }

        public override bool Equals(object obj)
        {
            if (isPersistentObject())
            {
                var persistentObject = obj as Entity;
                return (persistentObject != null) && (Id == persistentObject.Id);
            }

            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return isPersistentObject() ? Id.GetHashCode() : base.GetHashCode();
        }

        private bool isPersistentObject()
        {
            return (Id != 0);
        }
    }

    public class Team : Entity
    {
        public virtual string Name { get; set; }
        public virtual ISet<Employee> Employees { get; set; }

        public Team()
        {
            Employees = new HashedSet<Employee>();
        }
    }

    public class Employee : Entity
    {
        public virtual string LastName { get; set; }
        public virtual string FirstName { get; set; }
        public virtual ISet<Team> Teams { get; set; }
        public virtual string EMail { get; set; }

        public Employee()
        {
            Teams = new HashedSet<Team>();
        }
    }

マッピング:

public class TeamMap : ClassMap<Team>
{
    public TeamMap()
    {
        // identity mapping
        Id(p => p.Id).Column("TeamID");

        // column mapping
        Map(p => p.Name);

        // relationship mapping
        HasManyToMany(m => m.Employees)
            .Table("EmployeeTeam")
            .LazyLoad()
            .Cascade.SaveUpdate()
            .AsSet()
            .ParentKeyColumn("TeamID")
            .ChildKeyColumn("EmployeeID");
    }
}

public class EmployeeMap : ClassMap<Employee>
{
    public EmployeeMap()
    {
        // identifier mapping
        Id(p => p.Id).Column("EmployeeID");

        // column mapping
        Map(p => p.EMail);
        Map(p => p.LastName);
        Map(p => p.FirstName);

        // relationship mapping
        HasManyToMany(m => m.Teams).Table("EmployeeTeam")
            .Inverse()
            .Cascade.SaveUpdate()
            .AsSet()
            .LazyLoad()
            .ParentKeyColumn("EmployeeID")
            .ChildKeyColumn("TeamID");
    }
}

テスト:

[TestMethod]
public  void  CanCorrectlyMapEmployee()
{
    var team = new List<Team> {new Team() {Name = "Team1"}};

    new PersistenceSpecification<Employee>(_session)
        .CheckProperty(p => p.EMail, "Mail")
        .CheckProperty(p => p.FirstName, "Firstname")
        .CheckProperty(p => p.Id, 1)
        .CheckProperty(p => p.LastName, "Lastname")
        .CheckList(p => p.Teams,team )
        .VerifyTheMappings();
}

従業員を追加するかチームを追加するかにかかわらず、EmployeeTeamテーブルは常に空です。

FNHを使用したSQLLiteに対してテストし、SQLServer2008に対して手動でテストしました。

誰かがこれを修正するアイデアを持っていますか?

編集:

従業員を作成して2つのチームを従業員に追加し、作成した従業員をロードすると、彼には2つのチームがあることに驚きました。だからそれはうまくいきます。しかし、リレーションシップテーブルのEmployeeTeamを見ると、すべてが空です。誰かが私に理由を説明できますか?

そして、Fluent NHibernateを使用して多対多の関係をテストする方法を知っている人はいますか?

前もって感謝します!

4

1 に答える 1

3

従業員マップには逆属性があります。ご存知かもしれませんが、これは、従業員を保存すると、関係テーブル (EmployeeTeam) が更新されないことを意味します。新しい関係情報を追加/削除するには、従業員をチームに追加してチームを保存する必要があります。

したがって、あなたの場合、従業員側で多対多をテストするのではなく、チーム側でテストしてください。(チームを従業員に追加するときに NHibernate にレコードを追加させたい場合は、「反転」属性を反転する必要があります。従業員ではなくチームに与えますが、チーム エンティティと同じ話です)。

従業員にチームをロードできたのはなぜですか? セッションレベルのキャッシュのため。Employee を同じ ISession に保存してロードした可能性があります。これは、NHibernate がデータベースからロードせずに、同じオブジェクトへの参照を正確に返したことを意味します。2 つの異なるセッションで保存と読み込みを試してみると、Employee.Teams セットにチームが表示されません。

補足: 多対多の関係間の一貫性を強制するメソッドを作成することをお勧めします。つまり、Team を Employee に追加すると、Employee がチームに追加されます。このような:

class Employee 
{
  // ...
  public void AddTeam(Team team)
  {
     // check for null, etc. 

     Teams.Add(team);
     team.Employees.Add(this);
  }
}

Team クラスの非常によく似たメソッドです。

于 2009-11-26T09:23:46.567 に答える