流畅的NHibernate AutoMapping,应该可以节省时间,但这让我把头发拉了出来

时间:2009-09-13 20:30:50

标签: c# nhibernate orm fluent-nhibernate

我也是NHibernate和FNH的新手。我对ORM很熟悉,并决定看看这个特别的嗡嗡声是什么,主要是因为提高了生产力。在这一点上,我认为我的时间会更好地花在使用别的东西上,但我不想让这个让我失望,我希望这是一个愚蠢的错误我正在制作,因为我非常想让这给我留下深刻的印象。无论如何,我尝试手动映射实体(Fluent)无济于事,现在我正在尝试使用automap功能。这是我的域名模型。

public class Book
{
 public virtual int Id { get; protected set; }
 public virtual string Isbn { get; set; }
 public virtual string Title { get; set; }
 public virtual string Author { get; set; }
 public virtual string Publisher { get; set; }
 public virtual User Seller { get; set; }
 public virtual ICollection<string> Pics {get; private set;}
 public virtual string Condition { get; set; }
 public virtual decimal Price { get; set; }
 public virtual ExchangeMethod PreferedExchangeMethod { get; set; }
}
public class Course
{
 public virtual int Id { get; protected set; }
 public virtual University University { get; set; }
 public virtual Semester Semester { get; set; }
 public virtual string Description { get; set; }
 public virtual string Name { get; set; }
 public virtual ICollection<Book> RequiredBooks { get; private set; }
}
public class Exchange
{
 public virtual int Id { get; protected set; }
 public virtual User Buyer { get; set; }
        public virtual User Seller { get; set; }
        public virtual Book Book { get; set; }
        public virtual ExchangeMethod Method { get; set; }
        public virtual decimal Price { get; set; }
        public virtual int SellerFeedbackRating { get; set; }
        public virtual int BuyerFeedbackRating{get; set;}
        public virtual string SellerComment { get; set; }
        public virtual string BuyerComment { get; set; }
}
public class Semester
{
        public virtual int id { get; protected set; }
        public virtual University University { get; set; }
        public virtual int Year { get; set; }
        public virtual string Term { get; set; }
}
public class University
{
        public virtual string Name { get; set; }
        public virtual int Connections { get; set; }
        public virtual ICollection<Course> Courses { get; private set; }
}
public class User
{
        public virtual string UserName { get; set; }
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual string Email { get; set; }
        public virtual ICollection<Course> Enrollment { get; private set; }
        public virtual ICollection<Book> Library { get; private set; }
        public virtual ICollection<Exchange> Exchanges { get; private set; }
}

这是我的映射

public static ISessionFactory CreateSessionFactory()
{
 IPersistenceConfigurer persistenceConfigurer = SQLiteConfiguration.Standard.UsingFile(DbFile);
        return Fluently.Configure()
                .Database(persistenceConfigurer)
                .Mappings(m => m.AutoMappings.Add(
                    AutoMap.AssemblyOf<User>(assem => assem.Namespace == "DataTransferObjects")
                        .Override<User>(map => map.Id(user => user.UserName))
                        .Override<University>(map => map.Id(univ => univ.Name))
                    ))
                .ExposeConfiguration(BuildSchema)
                .BuildSessionFactory();
}
private static void BuildSchema(Configuration config)
{
 // delete the existing db on each run
        if (File.Exists(DbFile))
           File.Delete(DbFile);
        // this NHibernate tool takes a configuration (with mapping info in)
        // and exports a database schema from it
        new SchemaExport(config).Create(false, true);
}

这是我不断得到的错误,非常模糊:
XML验证错误:命名空间'urn:nhibernate-mapping-2.2'中的元素'class'在命名空间'urn:nhibernate-mapping-2.2'中具有无效的子元素'property'。期望的可能元素列表:命名空间'urn:nhibernate-mapping-2.2'中的'meta,subselect,cache,synchronize,comment,tuplizer,id,composite-id'

感谢您的帮助,感谢抱歉。

修改 我布置模型的方式是否使我容易出现循环逻辑错误,例如:用户有一本书,这本书有用户吗?我希望自动化能够选择它。

2 个答案:

答案 0 :(得分:3)

您使用的是最新版本的FNH和NHibernate 2.1 RTM吗?

我不太确定您对Id代码的覆盖。您是否尝试过没有这个并在每张桌子上都有ID?

以下是我使用Automap进行映射的方法。我告诉它要从哪个程序集中取出,特别是命名空间,然后我给它实体派生的BaseTypes。 我使用ConventionDiscovery来改变一些外键命名约定并设置级联和反向属性等。

PersistenceModel = AutoPersistenceModel
        .MapEntitiesFromAssemblyOf<>()
        .Where(type => type.Namespace != null && type.Namespace.Contains("Model"))
        .WithSetup(s =>
                     {
                       s.IsBaseType = type => type ==  typeof (DateTimeBase)
                                              || type == typeof (SimpleBase);
                     })
        .ConventionDiscovery.AddFromAssemblyOf();
然后我将持久性模型添加到自动化中。我使用ExportTo方法获取生成的xml文件的副本 - 查看xml有助于诊断某些问题。

.Mappings(m => m.AutoMappings
                         .Add(persistenceModel)
                         .ExportTo(@"../../ExportAutoMaps"));

AutoMapping对我来说非常有用 - 虽然它确实需要时间来学习和实验 我正在使用jet数据库,我必须为NHibernate显式创建我的数据库文件以运行架构。我不熟悉sqlLite的工作原理。

答案 1 :(得分:3)

好吧,因为我认为这是一个愚蠢的错误。对于学期实体,我有“id”而不是“Id”。有点令人失望的是FNH在进行自动化时是区分大小写的,我本来会想到“强类型”支持他们必须防止配置文件中的拼写错误。

仅供参考,默认情况下自动执行时会尝试映射到每个实体上名为“Id”的属性,除非您另行指定。