简体   繁体   English

FluentNhibernate一对一映射

[英]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. 默认情况下,动物是流浪动物(其所有者对象将为null),直到我们分配了所有者为止。 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: 我能够将数据插入数据库,而由nhibernate生成的sql是:

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. 数据确实出现在数据库中, 但是在调用Session.save(animal)之后,我得到了一个错误'NHibernate.AssertionFailure:null identifier'我认为问题出在SQL的最后一位“ select SCOPE_IDENTITY()”,该函数返回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? 谁能建议我如何在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). 根据您的映射,“所有者”表应该有一个名为“ animal_id”的列,用于存储 ID(主键)。 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. 但这与存储此Owner实例具有的动物的ID(外键)的列的名称相同。

Can you post your actual DB schema? 您可以发布实际的数据库架构吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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