欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ProjectManager System Develop:2. ProjectManger oralce database create

程序员文章站 2022-03-08 20:10:21
...

项目概述

需求

创建公司内部项目管理系统。

技术栈

数据库:oracle 11g

ORM:Entity Framework

框架:参考Osharp、Dos.ORM

项目实施

创建数据库

创建表空间及临时表空间

create tablespace projectmanager datafile '' size 100m autoextend on next 100m maxsize unlimited;

create temporary tablespace projectmanagertemporory tempfile '' size 100m autoextend on next 100m maxsize unlimited;

    创建表空间与临时表空间有两点不同,临时表空间需要增加temporary关键字,及文件路径标识表空间为datafile,临时表空间为tempfile。

创建用户及赋予权限

create user projectmanager identified by ***;

grant connect,resource,dba to projectmanager;

加载Oracle Entity Framework类包并配置

使用nuget下载

ProjectManager System Develop:2. ProjectManger oralce database create

如下两个包,首先下载ManagedDataAccess,然后在下载载EntityFramework。因为EntityFramework中自带ManagerDataAccess组件,而且版本有可能低于单独下载的组件,在开发中有可能出现不确定的问题。

在项目中下载完成这两个组件后,会在web.config中自动生成config节点需要手动配置节点信息:

<add name="default" providerName="Oracle.ManagedDataAccess.Client" connectionString="User Id=projectmanager;Password=***;Data Source=orcl" />

Data Source可以使用全名的方式也可以使用别名方式:

<dataSources>
        <dataSource alias="SampleDataSource" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL))) "/>
      </dataSources>

详细的code first内容可以参照点击打开链接这篇内容,进行详细的了解。

DataBase First 方式创建数据库表

创建内容包括,projects 表,users表,关联表projectuser以及主键相对应的序列和触发器。

-- CREATE TABLE PROJECTS
CREATE TABLE PROJECTS
(
  ID          NUMBER(10) NOT NULL,
  PROJECTNAME NVARCHAR2(250) NOT NULL,
  PROJECTCODE NCLOB,
  STARTDATE   DATE NOT NULL,
  FINISHTIME  DATE NOT NULL
);

--ADD PRIMARY KEY
ALTER TABLE PROJECTS
  ADD CONSTRAINT PK_PROJECTS PRIMARY KEY (ID);

--ADD PROJECTS SEQUENCE
CREATE SEQUENCE EFSE_PROJECT
INCREMENT BY 1
START WITH 1
NOMAXVALUE 
NOMINVALUE 
NOCACHE;

--ADD PROJECTS TRIGGER
CREATE OR REPLACE TRIGGER TRI_PROJECT
 BEFORE INSERT ON PROJECTS 
 FOR EACH ROW 
   BEGIN
     SELECT EFSE_PROJECT.NEXTVAL INTO :NEW.ID FROM DUAL;
     END;
create table USERS
(
    "ID" number(10, 0) not null, 
    "USERNAME" nclob null, 
    "USERCODE" nclob null, 
    "EMAIL" nclob null, 
    "EMAILCONFIRMED" number(1, 0) not null, 
    "PASSWORDHASH" nclob null, 
    "SECURITYSTAMP" nclob null,
    constraint "PK_USER" primary key ("ID")
);
create sequence EFSE_USER
 increment by 1
 start with 1
 nomaxvalue 
 nominvalue
 nocache;
 
 create or replace trigger TRI_USER
 BEFORE INSERT ON USERS
 FOR EACH ROW
   BEGIN
     SELECT EFSE_USER.NEXTVAL INTO :NEW.ID FROM DUAL;
     END;

	 create table PROJECTUSER
(
    ID INTEGER,
    PROJECTCODE VARCHAR2(255),
    USERCODE VARCHAR2(255)
);

CREATE SEQUENCE EFSE_PROJECTUSER
 INCREMENT BY 1
 START WITH 1
 NOMAXVALUE
 NOMINVALUE
 NOCACHE;
 
 CREATE OR REPLACE TRIGGER TRI_PROJECTUSER
 BEFORE INSERT ON PROJECTUSER
 FOR EACH ROW
   BEGIN
   SELECT EFSE_PROJECTUSER.NEXTVAL INTO :NEW.ID FROM DUAL;
   END;
--增加的内容
 create table SOURCECODE
(
ID int,
LANGUAGE varchar2(10),
CODEFILE blob
);

alter table PROJECTS add(SOURCECODEID int);

create sequence EFSE_SOURCECODE
increment by 1 
start with 1 
nomaxvalue 
nominvalue 
nocache;

create or replace trigger TRI_SOURCECODE
before insert on SOURCECODE
for each row
  begin
    select EFSE_SOURCECODE.NEXTVAL into :new.ID from dual;
    end;

create table PAYBACK
(
ID integer,
AMOUNTOFMONEY NUMBER(10,2)
);

--ADD PRIMARY KEY  
ALTER TABLE PAYBACK  
  ADD CONSTRAINT PK_PAYBACK PRIMARY KEY (ID);  
  
--ADD PROJECTS SEQUENCE  
CREATE SEQUENCE EFSE_PAYBACK  
INCREMENT BY 1  
START WITH 1  
NOMAXVALUE   
NOMINVALUE   
NOCACHE;  
  
--ADD PROJECTS TRIGGER  
CREATE OR REPLACE TRIGGER TRI_PAYBACK  
 BEFORE INSERT ON PAYBACK   
 FOR EACH ROW   
   BEGIN  
     SELECT EFSE_PAYBACK.NEXTVAL INTO :NEW.ID FROM DUAL;  
     END;  
 

由于bug部分有未解决问题本次开发没有采用code first的方式创建数据库,而是采用手动创建数据库表及相关内容。

BUG

1.获取objectDbContext错误:

访问数据库时出错。这通常意味着与数据库的连接失败。请检查连接字符串是否正确,以及是否正使用适当的 DbContext 构造函数指定它或者在应用程序的配置文件中找到它。有关 DbContext 和连接的信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=386386。有关失败的详细信息,请参阅内部异常。”

此错误解决方法参照code first配置章节,产生原因为配置信息错误造成。

2.连接oracle是报错,表或视图不存在:

在OnModelCreating方法中增加modelBuilder.HasDefaultSchema("PROJECTMANAGER");用户名要大些,oracle不区分大小写,而EntityFramework中用户名区分大小写,如果是数据库迁移,不能更改用户名为大写,则需要加双引号,使数据库内的用户名识别大小写。

3.error: ORA-06550:
PL/SQL: ORA-00942: 表或视图不存在ORA-06550

code frist 执行代码报错:通过查找原因发现需要手动设置数据库为更改时重新创建数据库,注意:如果数据库中存在重要数据则不能实用此方法,因为此方法覆盖原有数据表。

Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ProjectDbContext>());

4.Oracle.ManagedDataAccess.Client.OracleException:“ORA-08177: 无法连续访问此事务处理

现阶段还没有解决此问题,解决方式为自己手动创建数据库,屏蔽掉自动更新的代码。参考问题5中内容。

5.Model compatibility cannot be checked because the database does not contain model metadata. Model compatibility can only be checked for databases created using Code First or Code First Migrations

database frist 要屏蔽掉:

Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ProjectDbContext>());

更新的代码。

6.TheEntityFrameworkprovidertype'Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices,Oracle.ManagedDataAccess.EntityFramework,Version=6.122.1.0,Culture=neutral,PublicKeyToken=89b483f429c47342' registered in the application config file for the ADO.NET provider with invariant name 'Oracle.ManagedDataAccess.Client' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application

6.1增加FixEfProviderServicesProblem方法无效

参考链接戳这里,并没有解决问题,根据原文地址发现问题所阐述的环境为sqlservice数据库,怀疑这种解决方式只有在sqlservice数据库起作用。尝试通过更改为“oracle提供服务的实例”解决此问题,仍然没有得到解决。

var instance = Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices.Instance;

        public void FixEfProviderServicesProblem()
        {
            //The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer'  
            //for the 'System.Data.SqlClient' ADO.NET provider could not be loaded.   
            //Make sure the provider assembly is available to the running application.   
            //See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.  

            var instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance;
        }

6.2确定程序集是否引用失败

没有运行到构造函数已经出现异常,不能进行程序集是否引用的判断参考内容请戳这里

static MyContext() {
   Util.EnsureStaticReference<System.Data.Entity.SqlServer.SqlProviderServices>();
}
public static class Util
{
    public static void EnsureStaticReference<T>()
    {
        var dummy = typeof(T);
        if(dummy == null)
            throw new Exception("This code is used to ensure that the compiler will include assembly");
    }
}

6.3确定是否正确安装Entity Framework

经查看已经正确安装entity frameworkProjectManager System Develop:2. ProjectManger oralce database create

经确定已经正确安装了entity framework。

6.4确定machine.config配置文件是否存在oracle.manageddataaccess.client节点

检查目录C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config下是否存在该配置文件,该配置文件可以理解为app.config或者web.config的父配置文件。

 <section name="oracle.manageddataaccess.client" type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" />

如果存在查看版本是否一致参考链接。

6.5是否为下载的Oracle.ManagerDataAccess.Client的版本是否支持EF6

本次测试出现问题是在开发Web.API时产生的错误,如果在winform上并不会产生此错误,猜测不是因为版本不支持而导致的此错误。参考链接为与6.4相同。

6.6怀疑oracle client没有正确配置导致不能访问数据库

安装ODP.NET 官方下载路径。

6.7总结

经过两天的调试仍然没有解决问题,最后在没有办法的情况下通过entity framework的实体生成工具生成了实体文件,查看配置文件发现不是配置文件造成的问题。我在生成Web Api的时候更改过路径,重新整理思路,想到重新创建Web Api,没有更改生成路径,调试成功。问题就这样鬼使神差的解决了,最终也没有找到问题的原因,这个问题算是告一段落。

7.error:entity framework code first ORA-01400:

创建自增长主键解决问题。

//创建序列

create sequence PROJECT_SE
increment by 1
start with 1
nomaxvalue
nominvalue
nocache

//创建触发器

create or replace trigger project_tri
 before insert on projects
 for each row
   begin
     select project_se.nextval into :new.id from dual;

     end;

8.entity framework 不支持的关键字 user id

配置文件连接字符串有错,更改连接字符串参考连接字符串一节。

9.System.Data.Entity.DynamicProxies……不能序列化

更改DbContext属性:

this.Configuration.ProxyCreationEnabled = false;
参考链接