1

1 対 1 の双方向関係を使用して 2 つのオブジェクトをマップしようとしています。2 つのオブジェクト間の関係は必須ではありません。オブジェクトは次のとおりです。

public class Tenant
{
    public virtual int TenantId { get; set; }

    public virtual string Name { get; set; }

    public virtual Unit Unit { get; set; }
}

public class Unit
{
    public virtual int UnitId { get; set; }

    public virtual string UnitNumber { get; set; }

    public virtual int Rooms { get; set; }

    public virtual Tenant Tenant { get; set; }
}

そして、ここに私が使用しようとしているマッピングがあります:

public class Mappings : ClassMap<Unit>
{

    /*
     * Unit
     * ------------
     * UnitId (PK)
     * TenantId (FK)
     * Rooms
     * UnitNumber
     */

    public Mappings()
    {
        Id(x => x.UnitId).GeneratedBy.Identity();

        References(x => x.Tenant);

        Map(x => x.Rooms).Not.Nullable();
        Map(x => x.UnitNumber).Not.Nullable();
    }
}



public class TenantMapping : ClassMap<Tenant>
{
    /*
     * Tenant
     * -------------
     * TenantId (PK)
     * Name 
     */
    public TenantMapping()
    {
        Id(x => x.TenantId).GeneratedBy.Identity();

        Map(x => x.Name).Not.Nullable();

        HasOne(x => x.Unit).PropertyRef(x => x.Tenant);
    }
}

予想されるテーブル定義は、マッピング コメントにあります。マッピングを検証するために使用しているテストは失敗しています:

    [Test]
    public void SetTenantOnUnit()
    {
        int unitId = 0;
        int tenantId = 0;
        using (var session = factory.OpenSession())
        {
            var tenants = Builder<Tenant>.CreateListOfSize(5).Build();
            var unit = Builder<Unit>.CreateNew().Build();
            foreach(var tenant in tenants)  
                session.Save(tenant);

            session.Save(unit);

            unit.Tenant = tenants[3];
            tenantId = unit.Tenant.TenantId;
            session.SaveOrUpdate(unit);

            unitId = unit.UnitId;
        }

        using (var session = factory.OpenSession())
        {
            var unit = session.Get<Unit>(unitId);
            Assert.That(unit, Is.Not.Null);
            Assert.That(unit.Tenant, Is.Not.Null);
            Assert.That(unit.Tenant.TenantId, Is.EqualTo(tenantId), "Incorrect Tenant Id");
        }

    }

    [Test]
    public void SetUnitOnTenant()
    {
        int tenantId = 0;
        int unitId = 0;
        using (var session = factory.OpenSession())
        {
            var tenant = Builder<Tenant>.CreateNew().Build();
            var units = Builder<Unit>.CreateListOfSize(5).Build();
            session.Save(tenant);

            foreach(var unit in units)
                session.Save(unit);


            tenant.Unit = units[3];
            unitId = tenant.Unit.UnitId;

            session.SaveOrUpdate(tenant);
            tenantId = tenant.TenantId;
        }

        using (var session = factory.OpenSession())
        {
            var tenant = session.Get<Tenant>(tenantId);
            Assert.That(tenant, Is.Not.Null);
            Assert.That(tenant.Unit, Is.Not.Null);
            Assert.That(tenant.Unit.UnitId, Is.EqualTo(unitId), "Incorrect unit id");
        }
    }

ここにソース コードを含めました: https://bitbucket.org/crmckenzie/fluentnhibernate.discovery/overview

理想的には、どちらの側からでもリレーションシップを作成し、データベースに正常に保存できるようにすることです。私は StackOverFlow に関する他の 1 対 1 マッピングのトピックを読みましたが、どれも直接的ではないようです。この関係を正しくマッピングするにはどうすればよいですか?

4

1 に答える 1

0

session.Flush();アフターが欠落しているunitId = unit.UnitId;ためtenantId = tenant.TenantId;、割り当てはdbに保存されません。テナントとユニットが保存される理由は、NHibernateにすぐに挿入するように強制するためsession.Save()です。GeneratedBy.Identity()nhibernateを設定したため、データベースにIDを要求する必要があります。そうしないunitId = unit.UnitId;と、間違った結果が生成されます。

于 2012-05-31T12:40:34.327 に答える