2010-02-10 115 views
0

我已经遗留了一个遗留应用程序,我几乎无法控制。我需要映射一对一的关系,因为“用户可能有其中一个,我们称之为”拒绝“,但不能超过一个”存储在拒绝表中的数据非常大。FluentNhibernate映射一对一

无论如何,我已经简单地使用了猫,狗和主人这个模型。默认情况下,动物是流浪的(它的所有者对象将为空),直到我们分配一个所有者。猫和狗都是动物。这些类看起来像这样。根据法律规定,只许你一个宠物;-)

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; } 
} 

而对于动物和所有者映射文件是这样的:

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(); 
    } 
} 

现在的问题。我能够将数据插入到数据库中,并通过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 

的数据会出现在数据库中,然后我得到一个错误“NHibernate.AssertionFailure:空标识符”调用Session.save(动物)后,我认为问题是与SQL的最后一点“select SCOPE_IDENTITY()”,它返回null。这是因为所有者表主键需要来自动物表。

任何人都可以建议如何我可以在FNH中正确映射此?任何帮助appriciated。 戴

根据您的映射表模式

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] 

回答

0

,业主表应该有一个叫“animal_id”存储 ID(主键)列。但是,这与存储此业主实例拥有的动物的ID(外键)的列的名称相同。

您可以发布您的实际数据库架构吗?

+0

谢谢,刚添加它。人们可以将所有者名称作为动态表中的列,并将其称为owner_name,但在此我试图对1-2-1关系进行建模。我的命名和我的真实世界的例子可能不是那么好。 – 2010-02-10 17:14:54