我已经植入了一个遗留应用程序,我几乎无法控制。我需要映射一对一的关系,因为“一个用户可能拥有其中一个,我们称之为‘拒绝’,但不超过一个”拒绝表中存储的数据相当大。
不管怎样,我用猫、狗和一个主人简化了这个模型。默认情况下,动物是流浪的(它的所有者对象将为空),直到我们指定一个所有者。猫和狗都是动物。课程看起来是这样的。根据法律,你只能养一只宠物;-)
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
数据确实出现在数据库中,
但是
然后在调用session.save(animal)之后,我得到一个错误“nhibernate.assertionfailure:null identifier”。我认为问题出在返回null的sql“select scope_identity()”的最后一位。这是因为所有者表主键需要来自动物表。
有谁能建议我如何在fnh中正确地映射这个?得到任何帮助。
戴
表架构
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]