测试实体定义:
1.One端的类:DiseaseType(病种简称【DT】)
2.Many端的类:TestItem(测试项目简称【TI】)
3.One-Many关系的意义:一类病种有多个测试项目
/// <summary>
/// 病种
/// </summary>
public class DiseaseType
{
/// <summary>
/// 病种ID
/// </summary>
public Guid DiseaseTypeId { get; set; }/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }/// <summary>
/// 编号
/// </summary>
public string Number { get; set; }/// <summary>
/// 检验项目
/// </summary>
public IList<TestItem> TestItems { get; set; }
}
/// <summary>
/// 输入类型
/// </summary>
public enum InputType
{
/// <summary>
/// 定性:阳性/阴性
/// </summary>
Qualitative = 0,
/// <summary>
/// 定量
/// </summary>
Quantify,
/// <summary>
/// 图片
/// </summary>
Picture,
/// <summary>
/// 文本
/// </summary>
Text
}
/// <summary>
/// 检验项目
/// </summary>
public class TestItem
{
/// <summary>
/// 检验项目ID
/// </summary>
public Guid TestItemId { get; set; }/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }/// <summary>
/// 编号
/// </summary>
public string Number { get; set; }/// <summary>
/// 输入类型
/// </summary>
public InputType InputType { get; set; }/// <summary>
/// 所属病种
/// </summary>
public DiseaseType DiseaseType { get; set; }
}
映射文件:
1.DiseaseType.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false" namespace="Bynon.Sample.Model" assembly="Bynon.Sample.Model">
<class name="DiseaseType" table="DiseaseType">
<id name="DiseaseTypeId" column="DiseaseTypeId" type="Guid">
<generator class="assigned"/>
</id>
<property name="Name" column="Name" type="String" length="50"/>
<property name="Number" column="Number" type="string" length="50"/><bag name="TestItems" inverse="true">
<key column="DiseaseTypeId"/>
<one-to-many class="TestItem"/>
</bag>
</class>
</hibernate-mapping>
2.TestItem.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false" namespace="Bynon.Sample.Model" assembly="Bynon.Sample.Model">
<class name="TestItem" table="TestItem">
<id name="TestItemId" column="TestItemId" type="Guid">
<generator class="assigned"/>
</id>
<property name="Name" column="Name" type="String" length="50"/>
<property name="Number" column="Number" type="string" length="50"/>
<property name="InputType" column="InputType" type="int"/><many-to-one name="DiseaseType" column="DiseaseTypeId"/>
</class>
</hibernate-mapping>
以下是我通过修改【<bag name="TestItems" inverse="true">】尝试不同的测试。
保存测试
测试代码:
var diseaseType = new DiseaseType
{
DiseaseTypeId = Guid.NewGuid(),
Name = "霍乱弧菌",
Number = "001"
};
var items = new List<TestItem>{
new TestItem{
TestItemId=Guid.NewGuid(),
Name="分离鉴定",
Number="001",
InputType=InputType.Qualitative,
DiseaseType=diseaseType
},
new TestItem{
TestItemId=Guid.NewGuid(),
Name="噬菌体生物分离",
Number="002",
InputType=InputType.Qualitative,
DiseaseType=diseaseType
}
};
diseaseType.TestItems = items;
session.Persist(diseaseType);
测试1:Inverse = true,不指定cascade(默认值为none)
测试生成的Sql:
INSERT INTO DiseaseType (Name, Number, DiseaseTypeId) VALUES (@p0, @p1, @p2);@p0 = '霍乱弧菌', @p1 = '001', @p2 = f30e77e6-77a0-4858-a4ed-3f86aa2ab4a3
测试结果:通过
测试结果分析:只保存了病种,没保存测试项目。
【Inverse = true】表示DT与TI的关系(以下简称【关系】)由TI维护
【cascade=none】表示保存DT时不对TI做任何操作(插入、更新、删除)。
测试2:Inverse = true,cascade=all
测试生成的Sql:
INSERT INTO DiseaseType (Name, Number, DiseaseTypeId) VALUES (@p0, @p1, @p2);@p0 = '霍乱弧菌', @p1 = '001', @p2 = 7bac9d0e-24cb-43b6-81a4-97592837a628
INSERT INTO TestItem (Name, Number, InputType, DiseaseTypeId, TestItemId) VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = '分离鉴定', @p1 = '001', @p2 = Qualitative, @p3 = 7bac9d0e-24cb-43b6-81a4-97592837a628, @p4 = 50f757bc-5180-4b73-a6fc-254eaeecfe4d
INSERT INTO TestItem (Name, Number, InputType, DiseaseTypeId, TestItemId) VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = '噬菌体生物分离', @p1 = '002', @p2 = Qualitative, @p3 = 7bac9d0e-24cb-43b6-81a4-97592837a628, @p4 = d47e601f-dff6-4876-bd62-8652f2f80563
测试结果:通过
测试结果分析:完美方案。
【Inverse = true】表示关系由TI维护
【cascade=all】表示保存DT,同时对TI进行任何操作。
测试3:Inverse = false,不指定cascade
测试生成的Sql:
INSERT INTO DiseaseType (Name, Number, DiseaseTypeId) VALUES (@p0, @p1, @p2);@p0 = '霍乱弧菌', @p1 = '001', @p2 = 75934b85-ff22-46da-b38f-979a1d74cf0f
UPDATE TestItem SET DiseaseTypeId = @p0 WHERE TestItemId = @p1;@p0 = 75934b85-ff22-46da-b38f-979a1d74cf0f, @p1 = 3531a507-215b-4146-a8c1-5c156ad4de2a
测试结果:不通过
测试结果分析:为什么会抛出异常?
【Inverse = false】表示关系由DT维护,因此当执行INSERT语句后,便执行UPDATE语句,此UPDATE语句的目的只是更新关系。执行UPDATE 语句时出错了,因为TI还没插入到数据库里。
测试4:Inverse = false,cascade=all
测试生成的Sql:
INSERT INTO DiseaseType (Name, Number, DiseaseTypeId) VALUES (@p0, @p1, @p2);@p0 = '霍乱弧菌', @p1 = '001', @p2 = 89fb5e74-81eb-440f-873b-c1e396cbb3cc
INSERT INTO TestItem (Name, Number, InputType, DiseaseTypeId, TestItemId) VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = '分离鉴定', @p1 = '001', @p2 = Qualitative, @p3 = 89fb5e74-81eb-440f-873b-c1e396cbb3cc, @p4 = fc42fcfe-5373-44d9-8207-de895723fb4c
INSERT INTO TestItem (Name, Number, InputType, DiseaseTypeId, TestItemId) VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = '噬菌体生物分离', @p1 = '002', @p2 = Qualitative, @p3 = 89fb5e74-81eb-440f-873b-c1e396cbb3cc, @p4 = 6b99db2a-6b46-46bd-9256-60047b71d6fa
UPDATE TestItem SET DiseaseTypeId = @p0 WHERE TestItemId = @p1;@p0 = 89fb5e74-81eb-440f-873b-c1e396cbb3cc, @p1 = fc42fcfe-5373-44d9-8207-de895723fb4c
UPDATE TestItem SET DiseaseTypeId = @p0 WHERE TestItemId = @p1;@p0 = 89fb5e74-81eb-440f-873b-c1e396cbb3cc, @p1 = 6b99db2a-6b46-46bd-9256-60047b71d6fa
测试结果:通过 。
测试结果分析:实现期望的结果,但后面两条UPDATE 是多余的。
【Inverse = false】表示关系由DT维护,因此当保存DT时要更新DT与TI的关系。
【cascade=all】表示保存DT,同时对TI进行任何操作,因此产生两条插入TI的INSERT 。
删除测试:
测试1:Inverse = true,不指定cascade(默认值为none)
测试生成的Sql:
DELETE FROM DiseaseType WHERE DiseaseTypeId = @p0;@p0 = 7bac9d0e-24cb-43b6-81a4-97592837a628
测试结果:不通过
测试结果分析:外键约束错误
【Inverse = true】表示关系由TI维护
【cascade=none】表示删除DT时不对TI做任何操作
测试2:Inverse = false,不指定cascade
测试生成的Sql:
UPDATE TestItem SET DiseaseTypeId = null WHERE DiseaseTypeId = @p0;@p0 = 7bac9d0e-24cb-43b6-81a4-97592837a628
DELETE FROM DiseaseType WHERE DiseaseTypeId = @p0;@p0 = 7bac9d0e-24cb-43b6-81a4-97592837a628
测试结果:通过
测试结果分析:只删除了DT,TI没删除
【Inverse = false】表示关系由DT维护,所以得出UPDATE 语句删除与TI的关系
【cascade=none】表示保删除DT时不对TI做任何操作
测试3:Inverse = false, cascade = all
测试生成的Sql:
UPDATE TestItem SET DiseaseTypeId = null WHERE DiseaseTypeId = @p0;@p0 = 7bac9d0e-24cb-43b6-81a4-97592837a628
DELETE FROM TestItem WHERE TestItemId = @p0;@p0 = 50f757bc-5180-4b73-a6fc-254eaeecfe4d
DELETE FROM TestItem WHERE TestItemId = @p0;@p0 = d47e601f-dff6-4876-bd62-8652f2f80563
DELETE FROM DiseaseType WHERE DiseaseTypeId = @p0;@p0 = 7bac9d0e-24cb-43b6-81a4-97592837a628
测试结果:通过
测试结果分析:DT和TI都删除了,但多了一条UPDATE 语句。
【Inverse = false】表示关系由DT维护,所以得出UPDATE 语句删除与TI的关系
【cascade=all】表示删除DT,同时对TI进行删除,因此产生三条DELETE
测试4:Inverse = true, cascade = all
测试生成的Sql:
DELETE FROM TestItem WHERE TestItemId = @p0;@p0 = 50f757bc-5180-4b73-a6fc-254eaeecfe4d
DELETE FROM TestItem WHERE TestItemId = @p0;@p0 = d47e601f-dff6-4876-bd62-8652f2f80563
DELETE FROM DiseaseType WHERE DiseaseTypeId = @p0;@p0 = 7bac9d0e-24cb-43b6-81a4-97592837a628
测试结果:通过
测试结果分析:完美方案。
【Inverse = true】表示关系由TI维护
【cascade=all】表示删除DT,同时对TI进行删除,因此产生三条DELETE