一直没有在项目里用过NHibernate3.2的CodeFirst 这次因为项目需要用到Oracle数据库而我对EF对Oracle支持心里犯嘀咕所以为保险起见我用NHibernate,以前都是写就映射文件的,现在3.2里已经集成了Maping Bycode工具可以说是NHibernate对CodeFirst支持得很不错了!我也不想采用Xml文件了(至于原因大家都懂得的!)

明白了大多数的NHibernate映射参数采用CodeFist也应该不是什么难事!

所以今天就试了一把,以前也试过但只粗略的试了一下!出现了以下问题,(结果谷爹 度娘 一起用也没查到个所以然!只是找了一堆EFCodeFirst的东西,NHibernate的几乎很少)小弟真不知道是怎么回事儿,所以特向园子里的大侠请教!

废话不多说了,先上代码:

 public class Student
    {
        public virtual int StudentID { set; get; }
        public virtual string StudentName { set; get; }
        public virtual IList<CurrClass> CurrClasses { set; get; }
    }

    public class CurrClass
    {
        public virtual int ClassID { set; get; }
        public virtual int ClassName { set; get; }
      
        public virtual IList<Student> Students { set; get; }
    }

    public class CurrClassMap : ClassMapping<CurrClass>
    {
        public CurrClassMap()
        {
            this.Id(p => p.ClassID, map => {
                map.Generator(Generators.Native);
            });

            this.Property(p => p.ClassName);
           
            this.Bag(p => p.Students, map => {
                map.Table("Student_Class");
            });
        }
    }

    public class StudentMap : ClassMapping<Student>
    {
        public StudentMap()
        {
            this.Id(p => p.StudentID, map =>
            {
                map.Generator(Generators.Native);
            });
            this.Property(p => p.StudentName, map =>
            {
                map.Length(500);
            });
            this.Bag(p => p.CurrClasses, map => {
                map.Table("Student_Class");
            });
        }
    }

 用过的朋友一看就知道是个多对多的关系!看似没什么问题,那么我们来看下生成映射文件是不是够标准:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" namespace="DALTestCase.domain" assembly="DALTestCase" xmlns="urn:nhibernate-mapping-2.2">
  <class name="CurrClass">
    <id name="ClassID" type="Int32">
      <generator class="native" />
    </id>
    <property name="ClassName" />
    <bag name="Students" table="Student_Class">
      <key column="currclass_key" />
      <many-to-many class="Student" />
    </bag>
  </class>
  <class name="Student">
    <id name="StudentID" type="Int32">
      <generator class="native" />
    </id>
    <property name="StudentName" length="500" />
    <bag name="CurrClasses" table="Student_Class">
      <key column="student_key" />
      <many-to-many class="CurrClass" />
    </bag>
  </class>
</hibernate-mapping>

很不错!和手写的没两样!

再来看看我们生成的数据库脚本(我这里是用的Sql2005):

if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FKCF48CF07D9A53447]') AND parent_object_id = OBJECT_ID('Student_Class'))
alter table Student_Class  drop constraint FKCF48CF07D9A53447


    if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FKCF48CF07401A93]') AND parent_object_id = OBJECT_ID('Student_Class'))
alter table Student_Class  drop constraint FKCF48CF07401A93


    if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FKCF48CF077158C5E0]') AND parent_object_id = OBJECT_ID('Student_Class'))
alter table Student_Class  drop constraint FKCF48CF077158C5E0


    if exists (select * from dbo.sysobjects where id = object_id(N'CurrClass') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table CurrClass

    if exists (select * from dbo.sysobjects where id = object_id(N'Student_Class') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Student_Class

    if exists (select * from dbo.sysobjects where id = object_id(N'Student') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table Student

    create table CurrClass (
        ClassID INT IDENTITY NOT NULL,
       ClassName INT null,
       primary key (ClassID)
    )

    create table Student_Class (
        currclass_key INT not null,
       elt INT not null,///这里就是我说的莫名奇妙的多出来了一个字段
       student_key INT not null
    )

    create table Student (
        StudentID INT IDENTITY NOT NULL,
       StudentName NVARCHAR(500) null,
       primary key (StudentID)
    )

    alter table Student_Class 
        add constraint FKCF48CF07D9A53447 
        foreign key (elt) 
        references Student

    alter table Student_Class 
        add constraint FKCF48CF07401A93 
        foreign key (currclass_key) 
        references CurrClass

    alter table Student_Class 
        add constraint FKCF48CF077158C5E0 
        foreign key (student_key) 
        references Student

正在我看的时侯突然发现,第三个表里竟然多了一个elt的字段,到底是怎么回事儿呢!?现在我也没闹明白!怎么会凭空多个字段出来!?

结果表结构就变成了下面的这个样子:

 

至于生成的涉及Student_Class的这个表生成的SQL语句都会存在这个elt的字段。如果操作Student_Class表生成的SQL语句会出现不能执行的错误!

为什么会出现elt的字段?为什么用Xml就不会出现elt的字段?这个elt有什么用处!?

希望大侠们可以帮我解惑!!!

posted @ 2012-05-06 16:02 饭饭-1 阅读(849) 评论(4) 编辑

  public class Product
{
public int PID
{
get;
set;
}
public string PName
{
get;
set;
}

public virtual IList<Order> Orders
{
get;
set;
}
}

public class Order
{
public int OrderID
{
get;
set;
}

public string OrderName
{
get;
set;
}

public virtual IList<Product> Products
{
get;
set;
}
}

 映射配置:

 public class ProductConfig:EntityTypeConfiguration<Product>
{
public ProductConfig()
{
this.HasKey(p => p.PID);
this.Property(p => p.PName).HasMaxLength(255);
this.HasMany(p => p.Orders)
.WithMany(p => p.Products)
.Map(map => {
map.MapLeftKey("ProductID");
map.MapRightKey("OrderID");
map.ToTable("Product_Order");
});
}
}

public class OrderConfig : EntityTypeConfiguration<Order>
{
public OrderConfig()
{
this.HasKey(p => p.OrderID);
this.Property(p => p.OrderName).HasMaxLength(255);
}
}

 NH实体配置:

<class name="Product" table="T_Product">
<id name="PID" column="[PID]">
<generator class="native"/>
</id>
<property name="PName" column="PName" type="string" length="255"/>
<bag name="Orders" table="Product_Order">
<key column="ProductID"/>
<many-to-many class="Order" column="OrderID"/>
</bag>
</class>

<class name="Order" table="T_Order">
<id name="OrderID" column="[OrderID]">
<generator class="native"/>
</id>
<property name="OrderName" column="OrderName" type="string" length="255"/>
<bag name="Products" table="Product_Order">
<key column="OrderID"/>
<many-to-many class="Product" column="ProductID"/>
</bag>
</class>

 EF的Many to Many 关系清晰明了!实在没有什么好说的!

posted @ 2012-01-11 14:45 饭饭-1 阅读(452) 评论(1) 编辑

上篇比较NH和EF一对一的关系写得有点仓促。由于是第一次写Blog,写得不好请大家多多见谅。

在这里只对NH和EF OR 映射部分做个简单的对比,由于本人对EF还不太熟悉在这里不做深层讨论。

 

EF OR关系对本人来说理解的有点费劲,有时不知道是什么意思。(可能是我悟性太低吧!)

感谢大家的捧场!

一对多的关系我们拿学生和班级来做个例子。

下边是学生和班级的数据库结构图.:

 

班级和学生的对像模型图:

 

EF:学生和班级实体

public class Student

{


public int? StuID { get; set; }

public string StudentName { get; set; }

public virtual Class Class { set; get; }

public int? ClassID { get; set; }

}


 

 public class Class

{

public int? ClassID { get; set; }



public string ClassName { get; set; }



public virtual IList<Student> Students { get; set; }



}

 

   

NH:学生和班级实体

public class Student

{



public virtual int? StuID { get; set; }

public virtual string StudentName { get; set; }



}


 从对像模型上来看我更倾向NH,像EF上边的这样写感觉有点别扭!(主要还是在外键字段上)

   

 public class Class

{

public virtual int? ClassID { get; set; }



public virtual string ClassName { get; set; }



public virtual IList<Student> Students { get; set; }



}


 

 EF中学生和班级表实体关系定义:

 

public class StudentConfig : EntityTypeConfiguration<Student>

{

public StudentConfig()

{

this.HasKey(p => p.StuID).Property(p=>p.StuID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

this.Property(p => p.StudentName).HasMaxLength(255).HasColumnName("StudentName");

this.HasMany(p => p.Students).WithRequired(p => p.Class).HasForeignKey(p => p.ClassID);



this.ToTable("T_Student");

}

}


 

    

public class CLassConfig : EntityTypeConfiguration<Class>

{

public CLassConfig()

{

this.HasKey(p => p.ClassID).Property(p => p.ClassID)

.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

this.Property(p => p.ClassName).HasColumnName("ClassName").HasMaxLength(255);

this.ToTable("T_Class");



}

}


 

 

NH中学生和班级表实体关系定义:

 

<class name="Student" table="N_Student" lazy="true" >

<id name=" StuID " type="int" column=" StuID ">

<generator class="native"/>

</id>



<property name=" StudentName " type="string">

<column name=" StudentName " length="50"/>

</property>



</class>

 

 

 

 

 

 

<class name="Class" table="N_Class" lazy="true" >

<id name=" ClassID " type="int" column="ClassID">

<generator class="native"/>

</id>



<property name=" ClassName " type="string">

<column name=" ClassName " length="50"/>

</property>



<bag name="Students">

<key column=" ClassID"/>

<one-to-many class="Student"/>

</bag>



</class>

 

 

posted @ 2012-01-11 14:43 饭饭-1 阅读(341) 评论(0) 编辑

一直以来我都为寻找一个合适的Orm,以前用过NBear感觉不错,后来转到Nhibeante特别是Nhibeante的模型映射感觉很强大,也很顺手。随着做了几个项目之后,发现现在的好多项目是以数据库为中心的,往往和数据库设计的标准大相径庭,这就让我想起了当前有一面之缘的EF,听说EF升级到4.2网评反响不错!一直以来都没有升级到.net 4.0也许太我Out了吧!呵。。
元旦放假闲在家里没有事儿,所以看看EF。Orm既然是关系映射模型,那学Orm的时侯先学的就是关系映射。所有Orm关系无非就是:一对一,多对一(一对多),多对多。那我们就来对比一下Nh和EF是如何处理数据关系的。
一、    一对一关系映射
    一对一的关系映射最好的例子就是一个人都有一个身份证.下面我们就用这个例子。
   EF实体:
  UserInfo.cs
    public class UserInfo
    {
        public int userid
        {
            get;
            set;
        }

        public string username
        {
            get;
            set;
        }
  public int Carid
        {
            get;
            set;
        }

        public virtual CardInfo CardInfo
        {
            get;
            set;
        }


           
    }
     CardInfo.cs
    public class CardInfo
    {
        public  int Carid
        {
            get;
            set;
        }
        public string CardName
        {
            get;
            set;
        }
             
}

NH实体:
  UserInfo.cs
    public class UserInfo
    {
        Public virtual int userid
        {
            get;
            set;
        }

        Public virtual string username
        {
            get;
            set;
        }

        public virtual CardInfo CardInfo
        {
            get;
            set;
        }
          
    }
     CardInfo.cs
    public class CardInfo
    {
        Public virtual int Carid
        {
            get;
            set;
        }
        Public virtual string CardName
        {
            get;
            set;
        }
             
}


猛的一看这样的模型没错,不知道EF为什么不像NH一样不能自动创建外键(Carid)这样看起来不怎么符合领域模型。就因为这个让我习惯了好一会儿!比较之我更习惯NH映射的模型.这样子一看就知道一个人手里拿了一个身份证.

关系映射:
EF UserInfo映射类:
  public class UserInfoConfig : EntityTypeConfiguration<UserInfo>
    {
        public UserInfoConfig()
        {
            this.HasKey(p => p.userid);//定义主键
            this.Property(p => p.username).HasMaxLength(255);//普通属性映射
this.HasRequired(p => p.CardInfo).WithMany().HasForeignKey(p => p.Carid);//一对一的映射
            this.ToTable("T_UserInfo");//生成表
        }
    }
EF CardInfo映射类:

    public class CardInfoConfig : EntityTypeConfiguration<CardInfo>
    {
        public CardInfoConfig()
        {
            this.HasKey(p => p.Carid);
            this.Property(p => p.CardName).HasMaxLength(255);
            this.ToTable("T_CardInfo");
        }
    }
这样的映射是不是感觉很爽?我也是这么认为,可我还是不大习惯。可能是Nh 用XML映射用多了吧!让我们看下Nh One to One的映射.
 
<class name="UserInfo" table="N_UerInfo">
    <id name="userid" column="[userid]">
      <generator class="native"/>
    </id>
    <property name="username" type="string" column="[username]" length="255"/>
    <one-to-one name="CardInfo" constrained="true"/>
  </class>

  <class name="CardInfo" table="N_CardInfo">
    <id name="Carid" column="[Carid]">
      <generator class="native"/>
    </id>
    <property name="CardName" column="[CardName]" type="string" length="255"/>
  </class>


NH这样子映射虽然很麻烦但一看就能明白.很喜欢这样的。有很多人不喜欢XML映射说很麻烦,其实XML的可读性应该比程序好多了!至少我是这么认为的。一但多起来那就不那么好办了!
今天就到这了吧!下次再对比其他的几种关系。

posted @ 2012-01-03 14:56 饭饭-1 阅读(2149) 评论(7) 编辑