zoukankan      html  css  js  c++  java
  • Entity Framework Code First在Oracle下的伪实现(转)

    为什么要说是伪实现,因为还做不到类似MsSql中那样完全的功能。Oralce中的数据库还是要我们自己手动去创建的。这里,我们舍掉了Model First中的EDMX文件,自己在代码里面写模型与映射关系,这又有点像是Code First模型了,所以我说它是一个伪实现。真正完全的Code First应该是要通过Oracle开发驱动来支持了。

    通过EF来连接Oracle数据库,前提是要下载ODP.NET驱动。Google一下就找得到了。

    模型

    复制代码
      public class Student
        {
            public Student()
            {
                this.Teachers = new HashSet<Teacher>();
            }
            
            public Guid ID { get; set; }
            public string Name { get; set; }
            public int StudnetNumber { get; set; }
            public bool IsMale { get; set; }
    
            public virtual ICollection<Teacher> Teachers { get; set; }
        }
    
        public class Teacher
        {
            public Teacher()
            {
                this.Students = new HashSet<Student>();
            }
            public Guid ID { get; set; }
            public string Name { get; set; }
            public virtual ICollection<Student> Students { get; set; }
        }
    复制代码

    模型很简单,这里写了两个示例模型,Student 与Teacher,并且它们之间是多对多的关系。

    主键的配制

    Oralce数据库中主键有两种方式:后台通过数据库自己去生,比如:trigger+sequence结合的方式来产生自增长的主键;还有一种就是通过前台显示的给ID赋值,如ID=1来插入到数据库库中。如果你想通过前台自己手动来插入的话,要配置主键的自增长为NONE。

    HasKey(k => k.ID);
    Property(p => p.ID).HasColumnName("ID").HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

    数据类型的映射

    ODP.NET能够支持大多数数据类型的自动映射,比如int,datetime,string等。但对于一些特别数据类型,比如boolean,guid,Oracle数据库中并没有对应的bit类型或是GUID类型。我们要在映射的时候显示指定。

     //GUID类型的映射
     Property(p => p.TypeCode).HasColumnName("TYPECODE").HasColumnType("GUID");
     //boolean类型的映射
     Property(p => p.IsSale).HasColumnName("ISSALE").HasColumnType("odp_internal_use_type");

    关系的映射

    ODP.NET能够很好的支持一对多的映射,一对多的映射就像我们在配置MsSql数据库中一样。

    多对多关系的映射:因为两个多对多的表,会产生一个中间表,用来保存这两张表的主键,这就要求EF能够获得这两张表的主键。如果这两张表的主键是在数据库中通过Sequence来生成的,EF就无法获取。所以,如果要配置表之间的多对多关系,表的主键必须是通过前台显示插入的。

      HasMany(t => t.Teachers).WithMany(s => s.Students).Map(m =>
                    {
                        m.MapLeftKey("STUDENTID");
                        m.MapRightKey("TEACHERID");
                        m.ToTable("STUDENT_TEACHER", "GYOUNG");
                    });

    总的映射如下:

    复制代码
     public class StudentConfiguration : EntityTypeConfiguration<Student>
        {
            public StudentConfiguration()
            {
                HasKey(k => k.ID);
                Property(p => p.ID).HasColumnName("ID").HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
                    //GUID类型的映射
                    .HasColumnType("GUID");
                Property(p => p.Name).HasColumnName("NAME");
                //bool类型的映射
                Property(p => p.IsMale).HasColumnName("ISMALE").HasColumnType("odp_internal_use_type");
                Property(p => p.StudentNumber).HasColumnName("STUDENTNUMBER");
    
                HasMany(t => t.Teachers).WithMany(s => s.Students).Map(m =>
                    {
                        //LeftKey 当前表的主键
                        m.MapLeftKey("STUDENTID");
                        //RightKey 另一张表的主键
                        m.MapRightKey("TEACHERID");
                        //必须指定数据库架构名称
                        m.ToTable("STUDENT_TEACHER", "GYOUNG");
                    });
    
                //表名+数据库架构名
                ToTable("STUDENT", "GYOUNG");
            }
        }
    
        public class TeacherConfiguration : EntityTypeConfiguration<Teacher>
        {
            public TeacherConfiguration()
            {
                HasKey(k => k.ID);
                Property(p => p.ID).HasColumnName("ID").HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
                    .HasColumnType("GUID");
                Property(p => p.Name).HasColumnName("NAME");
                ToTable("TEACHER", "GYOUNG");
            }
        }
    复制代码

     DbContext

    复制代码
    public class TestContext : DbContext
        {
            public DbSet<Student> Students { get; set; }
            public DbSet<Teacher> Teachers { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Configurations.Add(new TeacherConfiguration()).Add(new StudentConfiguration());
                base.OnModelCreating(modelBuilder);
            }
    
        }
    复制代码

    附创建表的SQL:

    复制代码
    -- Creating table 'TEACHERS'
    CREATE TABLE "GYOUNG"."TEACHERS" (
       "ID" RAW(16) NOT NULL,
       "NAME" NVARCHAR2(200) NULL
    );
    
    -- Creating table 'STUDENTS'
    CREATE TABLE "GYOUNG"."STUDENTS" (
       "ID" RAW(16) NOT NULL,
       "NAME" NVARCHAR2(200) NULL,
       "ISMALE" NUMBER(10,0) NULL,
       "STUDENTNUMBER" NUMBER(10,0) NULL
    );
    
    -- Creating table 'STUDENT_TEACHER'
    CREATE TABLE "GYOUNG"."STUDENT_TEACHER" (
       "STUDENTID" RAW(16) NOT NULL,
       "TEACHERID" RAW(16) NOT NULL
    );
    复制代码

     忘记了配置,补贴一下:

    复制代码
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <configSections>
        <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      </configSections>
      <connectionStrings>
        <add name="MfTest" providerName="Oracle.DataAccess.Client" connectionString="Data Source=Gyoung;user id=test;password=123456" />
      </connectionStrings>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
      </startup>
      <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
      </entityFramework>
      <oracle.dataaccess.client>
        <settings>
          <add name="bool" value="edmmapping number(1,0)" />
          <add name="byte" value="edmmapping number(3,0)" />
          <add name="int16" value="edmmapping number(4,0)" />
          <add name="int32" value="edmmapping number(9,0)" />
          <add name="int64" value="edmmapping number(18,0)" />
        </settings>
      </oracle.dataaccess.client>
    </configuration>
    复制代码
    MfTest就是连接字符串,和SQLSERVER差不多,并没有什么关键的设计。数据库名是Gyoung,你自己要在Oracle中tnsnames.ora文件中去配置监听地址。
    ==================================================================================================
    转自:
    http://www.cnblogs.com/Gyoung/archive/2013/06/12/3132630.html
    作者:Elaine
    交流QQ:392989505
  • 相关阅读:
    Entity Framework 程序设计入门二 对数据进行CRUD操作和查询
    LLBL Gen + Entity Framework 程序设计入门
    企业管理软件开发之九 以数据绑定为基础的控件只读,创建时可写,必须大写,必须小写的原理与实现
    企业管理软件开发之八 多国语言功能设计与实现
    解析.NET 许可证编译器 (Lc.exe) 的原理与源代码剖析
    实用的开放源码的Excel导入导出类库 CarlosAg ExcelXmlWriter
    .NET程序集强命名删除与再签名技术 源代码剖析
    ibatis.net:第七天,QueryWithRowDelegate
    ibatis.net:第六天,QueryForList
    ibatis.net:第五天,QueryForObject
  • 原文地址:https://www.cnblogs.com/ITGirl00/p/3533647.html
Copyright © 2011-2022 走看看