为什么要说是伪实现,因为还做不到类似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" ) NOT NULL,
   "NAME" NVARCHAR2() NULL
);

-- Creating table 'STUDENTS'
CREATE TABLE "GYOUNG"."STUDENTS" (
   "ID" ) NOT NULL,
   "NAME" NVARCHAR2() NULL,
   "ISMALE" ,) NULL,
   "STUDENTNUMBER" ,) NULL
);

-- Creating table 'STUDENT_TEACHER'
CREATE TABLE "GYOUNG"."STUDENT_TEACHER" (
   "STUDENTID" ) NOT NULL,
   "TEACHERID" ) 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文件中去配置监听地址。

参考页面:.html

Entity Framework Code First在Oracle下的伪实现的更多相关文章

  1. Entity Framework Code First在Oracle下的伪实现(转)

    为什么要说是伪实现,因为还做不到类似MsSql中那样完全的功能.Oralce中的数据库还是要我们自己手动去创建的.这里,我们舍掉了Model First中的EDMX文件,自己在代码里面写模型与映射关系 ...

  2. Entity Framework Code First属性映射约定

    Entity Framework Code First与数据表之间的映射方式有两种实现:Data Annotation和Fluent API.本文中采用创建Product类为例来说明tity Fram ...

  3. Entity Framework Code First关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  4. Entity Framework Code First实体对象变动跟踪

    Entity Framework Code First通过DbContext.ChangeTracker对实体对象的变动进行跟踪,实现跟踪的方式有两种:变动跟踪快照和变动跟踪代理. 变动跟踪快照:前面 ...

  5. Entity Framework Code First (三)Data Annotations

    Entity Framework Code First 利用一种被称为约定(Conventions)优于配置(Configuration)的编程模式允许你使用自己的 domain classes 来表 ...

  6. Entity Framework Code First (二)Custom Conventions

    ---------------------------------------------------------------------------------------------------- ...

  7. Entity Framework Code First (一)Conventions

    Entity Framework 简言之就是一个ORM(Object-Relational Mapper)框架. Code First 使得你能够通过C#的类来描述一个模型,模型如何被发现/检测就是通 ...

  8. Entity Framework Code First 映射继承关系

    转载 http://www.th7.cn/Program/net/201301/122153.shtml Code First如何处理类之间的继承关系.Entity Framework Code Fi ...

  9. Entity Framework Code First主外键关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

随机推荐

  1. SuperWebClient -一个基于CURL的.NET HTTP/HTTPS模拟神组件(1)

    我们都知道,不管你是做爬虫也好,采集工具也罢,它们的HTTP/HTTPS模拟访问总是一个基础问题,我估计有很多人和我一样,虽然这样,那样的内置或是第三方类库用了很多,却总是会有一些不如意的问题存在,亦 ...

  2. JS中的作用域链

    在js中数据的声明方式有两种: 1.用var声明,例如:var num = 10: 2.直接声明,例如:num = 10: 两种声明方式在某些情况下是有区别的: var data = 10; func ...

  3. CSS常用字体Unicode 编码

    在 CSS 中设置字体名称,直接写中文是可以的.但是在文件编码(GB2312.UTF-8 等)不匹配时会产生乱码的错误. 为此,在 CSS 直接使用 Unicode 编码来写字体名称可以避免这些错误. ...

  4. Effective c++ Item 28 不要返回对象内部数据(internals)的句柄(handles)

    假设你正在操作一个Rectangle类.每个矩形可以通过左上角的点和右下角的点来表示.为了保证一个Rectangle对象尽可能小,你可能决定不把定义矩形范围的点存储在Rectangle类中,而是把它放 ...

  5. 自定义分页Gridview中Excel导出

    先上图,如图所示导出所有查询出的数据 用的是AspNetPager分页控件,这个导出方法,不受分页和gridview列中数据的约束,可以导出您想导出的数据 首先前台页面代码,lblink即为导出exc ...

  6. 基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-3

    来个目录吧: 第一章 第二章 第三章 暂时就这么多.后面路线更新吧 创建.查询.更新.删除 这章主要讲解使用EF完成 增删改查的功能. 自定义"详情信息"页面 我们通过基架生成的代 ...

  7. 3381: [Usaco2004 Open]Cave Cows 2 洞穴里的牛之二

    3381: [Usaco2004 Open]Cave Cows 2 洞穴里的牛之二 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 21  Solved ...

  8. 长连接 Socket.IO

    概念 说到长连接,对应的就是短连接了.下面先说明一下长连接和短连接的区别: 短连接与长连接 通俗来讲,浏览器和服务器每进行一次通信,就建立一次连接,任务结束就中断连接,即短连接.相反地,假如通信结束( ...

  9. 有关ospf抓包

    有关ospf抓包 1.相关的路由器为这样子的: 路由器都运行了ospf: 抓包的链路为GE0/0/2 , 2.抓包图: 从图上我们可以看到,protocol info 这一栏里面出现了: hello ...

  10. OnsenUI和AngularJS配合搭建混合应用的基本步骤

    混合开发的热潮已经掀起,实现混合开发的方式很多.今天给大家介绍一个实现混合开发的基本方法-OnsenUI和AngularJS配合. OnsenUI是一个可以实现混合开发的前端框架,包含了很多前端设计中 ...