【问题标题】:Testing NHibernate Map测试 NHibernate 地图
【发布时间】:2012-11-22 16:39:51
【问题描述】:

测试 NHibernate 映射类的最佳方法是什么?

假设我想测试以下地图:

public QuoteMap()
{
    this.Table("QUOTE");
    this.Id(x => x.Id).Column("QUOTE_ID").GeneratedBy.Sequence("SEQ_QUOTE_ID");
    this.Map(x => x.IsDeleted).Column("IS_DELETED");
    this.References(x => x.Proposal).Column("PROPOSAL_ID");
}

其中Proposal 类型映射到另一个表。

QUOTE 表如下所示:

CREATE TABLE "QUOTE"
  (
    "QUOTE_ID"    NUMBER(18,0) NOT NULL,
    "PROPOSAL_ID" NUMBER(18,0) NOT NULL ENABLE,
    "IS_DELETED"  NUMBER(1,0) DEFAULT 0 NOT NULL ENABLE,

    CONSTRAINT "PK_QUOTE" PRIMARY KEY ("QUOTE_ID"),
    CONSTRAINT "FK_QUOTE_PROPOSAL" FOREIGN KEY ("PROPOSAL_ID") REFERENCES
        "PROPOSAL" ("PROPOSAL_ID") ENABLE
  )

选项1:PersistenceSpecification

new PersistenceSpecification<Quote>(session, new CustomEqualityComparer())
    .CheckProperty(c => c.TenantId, 1)
    .CheckProperty(c => c.IsDeleted, false)
    .CheckReference(
        c => c.Proposal,
        new Proposal
            {
                Id = 1,
                IsDeleted = false,
                TenantId = 1,
                VersionNumber = 1,
                OutletId = 1,
                StatusId = "TST"
        })
    .VerifyTheMappings();
transaction.Commit();

...此测试将失败并出现以下异常:

NHibernate.Exceptions.GenericADOException:无法插入: [引用#18][SQL:插入 INTO QUOTE(IS_DELETED、PROPOSAL_ID、QUOTE_ID) 值(?,?,?)] ---> Oracle.DataAccess.Client.OracleException: ORA-02291: 完整性约束 (PROPOSALOWN.FK_QUOTE_PROPOSAL) 违反 - 未找到父键

...因为它依赖于带有Id = 1 的提案记录。 另一个问题是,如果您将PropertyA 映射到ColumnBPropertyBColumnA,您的测试将通过并且不会指出您的错误。

选项 2:原始 SQL 到 INSERT,NHibernate 到 SELECT 现在这将是理想的:您通过发出原始 SQL 语句来插入,例如

INSERT INTO QUOTE (QUOTE_ID, PROPOSAL_ID, IS_DELETED) 
  SELECT SEQ_QUOTE_ID.NextVal, 1, 0 from dual;

然后您使用 Nhibernate 阅读并检查值。 问题再次是依赖于 PROPOSAL 记录的存在。插入此测试的提案记录?当然!但是,Proposal 表有另一组 FOREIGN KEYS,因此您可能最终将 ROWS 插入到数十个表中,只是为了测试您的映射...不可能!

当然有更好、更简单的方法来测试 NHibernate Maps。你能推荐一个吗?

【问题讨论】:

    标签: c# nhibernate orm fluent-nhibernate nhibernate-mapping


    【解决方案1】:

    您应该使用CheckReference 进行提案:

    .CheckReference(
            c => c.Proposal,
            new Proposal
                {
                    IsDeleted = false,
                    TenantId = 1,
                    VersionNumber = 1,
                    OutletId = 1,
                    StatusId = "TST"
            })
    

    【讨论】:

    • 是的,对不起。问题仍然存在(未找到父键)
    • 您确定您像我在代码中所做的那样删除了Id 行吗? TenantId、OutletId 和 StatusId 呢?这些是否也引用了其他表?
    • 您的实体“提案”首先不应该有 ID,但应该有真实的参考 - 你不这么认为吗?
    • 是的,无论如何映射“PropertyA 到 ColumnB 和 PropertyB 到 ColumnA”的问题仍然存在。
    • @Tsar:无论如何,您应该将其作为一个单独的问题提出。 :-)
    猜你喜欢
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多