【问题标题】:Fluent NHibernate PersistenceSpecificationFluent NHibernate 持久性规范
【发布时间】:2009-11-20 21:55:07
【问题描述】:

我收到以下错误消息:

System.IndexOutOfRangeException:此 SqlParameterCollection 的索引 9 无效,Count=9..

我非常想知道为什么 oO?!

数据库架构和 hbm.xml 文件都是使用 FluentNHibernate 正确创建的。 CanCorrectlyMapBook方法出现错误,PersistenceSpecificationTest运行无错误。

[TestClass]
public class PersistenceSpecificationTests
{
    private static ISession _session;

    [TestInitialize]
    public void PersistenceSpecificationTest()
    {
        _session = Helper.CreateSessionFactory(false, false).OpenSession();
    }

    [TestMethod]
    public void CanCorrectlyMapBook()
    {
        new PersistenceSpecification<Book>(_session)
            .CheckProperty(p => p.IncludesCDDVD, true)
            .CheckProperty(p => p.Isbn, "1232324983sfdsdkfj")
            .CheckProperty(p => p.Name, "My Book")
            .VerifyTheMappings();
    }
}

数字 9 可能来自这本书的列数。起初我以为我必须检查所有属性,但我在另一个项目中用另一个实体对此进行了测试,它工作正常。

有人有想法吗?

编辑:

这里是我的域对象 + 映射:

    public interface IEntity
    {
        int Id { get; set; }
    }

    public abstract class LoanedItem : IEntity
    {
        public virtual int Id { get; set; }

        public virtual DateTime DateOfIssue { get; set; }

        public virtual bool IsLoaned { get; set; }

        public virtual String Name { get; set; }

        public virtual Employee LoanedBy { get; set; }

        public virtual Release Release { get; set; }

        public virtual Publisher Publisher { get; set; }

        public virtual bool IncludesCDDVD { get; set; }

    }

    public  class Book : LoanedItem
    {
        public virtual string Isbn { get; set; }

        public virtual int Author { get; set; }

    }

 public class BookMap : ClassMap<Book>
    {
        public BookMap()
        {
            // identity mapping
            Id(p => p.Id).Column("BookID");

            // column mapping
            Map(p => p.Author);
            Map(p => p.Isbn);
            Map(p => p.IncludesCDDVD);
            Map(p => p.IsLoaned);
            Map(p => p.Name);

            // component mapping
            // Publisher
            Component(p => p.Publisher, m =>
            {
                m.Map(x => x.Name);
                m.Map(x => x.Homepage);
            });

            // Release
            Component(p => p.Release, m =>
            {
                m.Map(x => x.ReleaseDate);
                m.Map(x => x.ReleaseNumber);
            });

            // reference/association 
            References(p => p.LoanedBy).Column("EmployeeID");
        }

编辑:

好的,上面的问题可以解决了。

但是如何检查组件?当我使用 CheckProperty 检查组件时,会发生错误...“预期为 'DomainModel.Model.Book' 但得到 'DomainModel.Model.Book' ... 呃 :) 那里有什么问题?它是完全相同的域对象。我创建了一个新的question

【问题讨论】:

  • 是的,请提供您的图书映射和图书实体。另一方面,这就是我不使用 PersistenceSpecification 的原因。当出现问题时,您不能“破坏”它打开并调试它。我更喜欢编写一个保存和加载类,使用 NBuilder 生成一个实体,然后保存/加载它以确认它是持久的。通过这种方式,您可以设置断点并检查局部变量以查看它们在任何给定点的值。

标签: unit-testing fluent-nhibernate


【解决方案1】:

问题可能是名称属性。您有 2 个名为“名称”的属性 - 一个在 Book 中,一个在 Publisher 组件中。 AFAIR FluentNHibernate 会将这两个属性映射到“NAME”列(检查生成的 hbms),这会导致您遇到错误。

尝试为这些属性之一指定不同的列名(最好在 Publisher 组件中 - 添加前缀左右),看看这是否有帮助。

【讨论】:

  • 非常感谢这是正确的答案 :) 但我问自己,为什么 Fluent NHibernate 没有警告我?
【解决方案2】:

我刚刚在一个新项目中尝试了您的代码,将 POCO 和映射简化为仅您在测试类中测试的内容。这就是我所拥有的:

public abstract class LoanedItem
{
    public virtual int Id { get; set; }
    public virtual String Name { get; set; }
    public virtual bool IncludesCDDVD { get; set; }
}

public class Book : LoanedItem
{
    public virtual string Isbn { get; set; }
}

public class BookMap : ClassMap<Book>
{

public BookMap()
{
    // identity mapping
    Id(p => p.Id).Column("BookID");

    // column mapping
    Map(p => p.Isbn);
    Map(p => p.IncludesCDDVD);
    Map(p => p.Name);
}

还有测试运行者:

[TestClass]
public class PersistenceSpecificationTests
{
    private static ISession _session;

    [TestInitialize]
    public void PersistenceSpecificationTest()
    {
        var cfg = Fluently.Configure()
            .Database(SQLiteConfiguration.Standard.InMemory().UseReflectionOptimizer())
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Book>())
            .BuildConfiguration();

        _session = cfg.BuildSessionFactory().OpenSession();
        new SchemaExport(cfg).Execute(false, true, false, _session.Connection, null);
    }

    [TestMethod]
    public void CanCorrectlyMapBook()
    {
        new PersistenceSpecification<Book>(_session)
            .CheckProperty(p => p.IncludesCDDVD, true)
            .CheckProperty(p => p.Isbn, "1232324983sfdsdkfj")
            .CheckProperty(p => p.Name, "My Book")
            .VerifyTheMappings();
    }
}

它使用内存中的 SQLite 数据库。测试顺利通过,所以问题肯定出在其他地方。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多