Ralf Thompson
Ralf Thompson

Reputation: 1

add objects with child collections

I have two classes: a Site class and a Phase class. The Site class defines a collection of Phases. Each class corresponds to a database table. The database (SQL Server 2000) has a one to many reference between the two tables such that a given Site can be associated with many Phases but a given Phase can only be associated with a single Site.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

public class Site
{
    public virtual int Id {get; set;}

    [Required]
    [Editable(true)]
    [StringLength(64)]
    public virtual string Name { get; set; }

    public virtual ICollection<Phase> Phases {get; set;}
}

public class Phase
{
    public virtual int Id {get; set;}

    [Required]
    [Editable(true)]
    [StringLength(64)]
    public virtual string Name { get; set; }

    [Editable(true)]
    [StringLength(16)]
    public virtual string Code { get; set; }

    public virtual int SiteId {get; set;}
    public virtual Site Site {get; set;}
}

I'm using FluentNHibernate to do my mapping. I want to map this in such away that I can create a new Site instance, assign a few Phase instances and make one call to get all instances into the database:

Site site = new Site() { Name = "SiteName" };
Phase phase = new Phase() { Name = "PhaseName", Code = "Code" };
Phase otherPhase = new Phase() { Name = "OtherPhaseName" };

site.Phases.Add(phase);
site.Phases.Add(otherPhase);

Session.SaveOrUpdate(site);

I have the following mappings in place, but they aren't doing the trick:

public class SiteMap : ClassMap<Site>
{
    public SiteMap()
    {
        Id(p => p.Id).Column("ST_ID").GeneratedBy.Native();
        Map(p => p.Name).Column("ST_Name");

        HasMany<Phase>(x => x.Phases).KeyColumn("ST_ID").LazyLoad().Inverse().AsSet();
    }
}

public class PhaseMap : ClassMap<Phase>
{
    public PhaseMap()
    {
        Id(p => p.Id).Column("PH_ID").GeneratedBy.Native();
        Map(p => p.Name).Column("PH_Name");
        Map(p => p.Code).Column("PH_Code").Nullable();
        Map(p => p.SiteId).Column("ST_ID");

        References<Site>(x => x.Site).Column("ST_ID").LazyLoad(Laziness.Proxy).Not.Insert().Not.Update();
    }
}

I'm new to NHibernate generally, so I recognize there may be other issues with the mappings shown here that I'm not aware of. Any assistance on how best to map these two classes would be appreciated. TIA.

Upvotes: 0

Views: 441

Answers (1)

Vadim
Vadim

Reputation: 17957

References<Site>(x => x.Site).Column("ST_ID").LazyLoad(Laziness.Proxy).Not.Insert().Not.Update();

Should just be

References<Site>(x => x.Site).Column("ST_ID").LazyLoad(Laziness.Proxy);

Your Not Insert and Update specifications do not update this column when you're insert or update the table.

You also need to specify Cascade on your one to many end

HasMany<Phase>(x => x.Phases).KeyColumn("ST_ID").Cascade.AllDeleteOrphan().LazyLoad().Inverse().AsSet();

Upvotes: 1

Related Questions