简体   繁体   中英

FluentNhibernate mapping one-to-one

I have inhertited an legacy application, that I have little control over. I need to map a one to one relationship because "A user may have one of these, lets call them 'a Rejection', but not more than one" The data stored in the Rejection table is quite large.

Anyway, I have simplyfied this model, using cats, dogs and an owner. An animal, by default, is stray (its owner object will be null), until we assign an owner. Cats and dogs are both animals. The classes look like this. By law, you are only allowed one Pet ;-)

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

public class Animal : Entity {
    public virtual string Name { get; set; }
    public virtual Owner Owner { get; set; }
}

public class Dog : Animal {
    public virtual string Bark { get; set; }
}

public class Cat : Animal {
    public virtual string Colour { get; set; }
}

public class Owner : Entity {
    public virtual string Name { get; set; }
    public virtual Animal Pet { get; set; }
}

And the mapping files for the Animal and Owner are like this:

public class OwnerMap : ClassMap<Owner> {
    public OwnerMap() {
        Id(x => x.Id).Column("animal_id");
        Map(x => x.Name);
        References(x => x.Pet, "animal_id").Cascade.SaveUpdate().ForeignKey();
    }
}
public class AnimalMap : ClassMap<Animal> {
    public AnimalMap() {
        Id(x => x.Id).Column("animal_id");
        Map(a => a.Name);
        HasOne(x => x.Owner).PropertyRef(p => p.Pet).Cascade.All().Fetch.Join();
    }
}

Now for the problem. I am able to insert the data into the database, and the sql generated by nhibernate is:

INSERT INTO [Animal] ([Name]) VALUES (@p0); select SCOPE_IDENTITY();@p0 = 'Odie'
INSERT INTO [Dog] ([Bark], [animal_id]) VALUES (@p0, @p1);@p0 = 'bark', @p1 = 1
INSERT INTO [Owner] ([Name], [animal_id]) VALUES (@p0, @p1); select SCOPE_IDENTITY();@p0 = 'Jon', @p1 = 1

The data does appear in the database, but then I get an error ' NHibernate.AssertionFailure: null identifier' after calling Session.save(animal) I think the problem is with the last bit of SQL "select SCOPE_IDENTITY()" which returns null. This is because the Owner Table primary key needs to come from the Animal Table.

Can anyone suggest how I could map this correctly in FNH? Any help appriciated. Dai

the table Schema

CREATE TABLE [dbo].[Animal](
    [animal_id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NULL, 
    CONSTRAINT [PK_Animal] PRIMARY KEY CLUSTERED ([animal_id] ASC ) 
    WITH PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,
    ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) 
ON [PRIMARY]) ON [PRIMARY]


CREATE TABLE [dbo].[Owner](
    [animal_id] [int] NOT NULL,
    [Name] [nvarchar](50) NULL, CONSTRAINT [PK_owner2] 
    PRIMARY KEY CLUSTERED (
    [animal_id] ASC )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
    IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)
    ON [PRIMARY] ) ON [PRIMARY]

Based on your mapping, the Owner table should have a column called "animal_id" that stores its ID (its primary key). But that's the same as the name of the column that stores the ID (foreign key) of the animal that this instance of Owner has.

Can you post your actual DB schema?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM