Oracle + EF5 疑难杂症

系统 1733 0
原文: Oracle + EF5 疑难杂症

PDF 版

http://files.cnblogs.com/xling/Oracle.pdf

Oracle 环境准备

ODAC

ODAC 全称 Oracle Data Access Components

下载:

 

ODTWthODAC 是用于VS的开发工具.

 

安装

采用ODAC XCopy 版, 就不需要安装体积庞大的 Oracle Client 了.

  1. 将 ODAC 解压到一个固定的位置, 比如 C:\ODAC , 注意, 这个文件夹用完后不能删除
  2. 以管理员身份打开一个 CMD
  3. Cd C:\ODAC\ODP.NET\Managed\X64
  4. 运行 configure.bat ( 不要图快,直接右键以管理员身份运行, 没用! )

    Oracle + EF5 疑难杂症

  5. 运行成功后, 会注册相关DLL到GAC中.
  6. 打开 Machine.config (C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config)

    可以看到加入了一个 setion oracle.manageddataaccess.client,

    在 DbProviderFactories 下加入了 ODP.NET, Managed Driver

    对应 section oracle.manageddataaccess.client 还有一个配置:

              
                 1
              
              
                <
              
              
                oracle.manageddataaccess.client
              
              
                >
              
              
                 2
              
              
                 3
              
              
                <
              
              
                version 
              
              
                number
              
              
                ="4.121.1.0"
              
              
                >
              
              
                 4
              
              
                 5
              
              
                <
              
              
                settings
              
              
                >
              
              
                 6
              
              
                 7
              
              
                <
              
              
                setting 
              
              
                name
              
              
                ="tns_admin"
              
              
                 value
              
              
                ="c:\odac\odp.net\managed\x64\..\..\..\network\admin"
              
              
                />
              
              
                 8
              
              
                 9
              
              
                </
              
              
                settings
              
              
                >
              
              
                10
              
              
                11
              
              
                </
              
              
                version
              
              
                >
              
              
                12
              
              
                13
              
              
                </
              
              
                oracle.manageddataaccess.client
              
              
                >
              
            

     

     

    其中, setting tns_admin 所指的地址即 tnsnames.ora 的目录.

  7. 将 D:\ODAC\network\admin\sample\tnsnames.ora 考到上一层目录:

    即 c:\ODAC\network\admin\

    修改成 :

              
                1
              
              
                dev =
    
    
              
              
                2
              
              
                  (DESCRIPTION =
    
    
              
              
                3
              
              
                    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.3)(PORT = 1521))
    
    
              
              
                4
              
              
                    (CONNECT_DATA =
    
    
              
              
                5
              
              
                      (SERVER = DEDICATED)
    
    
              
              
                6
              
              
                      (SERVICE_NAME = ORCL)
    
    
              
              
                7
              
              
                    )
    
    
              
              
                8
              
                 )
            

     

     

    DEV 即别名, 不区分大小写

    HOST 即 ORACLE 服务器地址

    PORT 为指定的监听端口

    SERVICE_NAME 即ORACLE 实例名

     

    如果需要 32位的, 可以重复上面的步骤, 不过运行的是 X86目录下面的 configure.bat 而已.

     

    ODTWithODAC 一路 NEXT 即可.

    在 VS 中连接数据库, 即可看到多出一个 ODP.NET 托管驱动程序选项:

    Oracle + EF5 疑难杂症

    用TNS 测试连接:

    Oracle + EF5 疑难杂症

    注意: 这里的 Tnsnames.ora 的位置, 不是上面步骤中的位置 . 如果文件不存在, 请在 COPY一个到 admin 目录下.

     

    用 EZ 测试连接:

    Oracle + EF5 疑难杂症

网站运行可能出现的错误:

无法读取配置节 Oracle.manageddataaccess.client 因为它缺少节声明

请检查你的应用程序池
Oracle + EF5 疑难杂症

A, 如果 "启用32位应用程序"为 True , 请改为 False , 因为只安装了 64 位的 ODAC

B, 也可以把 32 位的 ODAC 安装上.

 

Entity Framework

支持

当前EF6 不支持 Oracle, 而且只能是 Database First .

表名/字段名 大小写的问题

在Oracle 中建的表, 在更新模型的时候, 全是大写, 表字段也全是大写:

Oracle + EF5 疑难杂症

 

这个问题对于习惯于 SQLServer 的你来说, 感觉一定是吹鼻子瞪眼,抓狂的想办法把表名变小写.

有办法变小写, 不过,了解了因果之后, 你一定会想:大写就大写吧.

 

建表语句 中的 表名/列名 用双引号括起来 :

      
        1
      
      
        CREATE
      
      
        TABLE
      
      
         BK."Test"


      
      
        2
      
      
        (


      
      
        3
      
           "ID" 
      
        NUMBER
      
      
        NOT
      
      
        NULL
      
      
        ,


      
      
        4
      
           "Name" 
      
        NUMBER
      
      
        NOT
      
      
        NULL
      
      
        5
      
       )
    

 

生成的表, 可以看到 表名/列表都有小写的字母了.

Oracle + EF5 疑难杂症

但是:

Oracle + EF5 疑难杂症

必须用

      
        SELECT
      
      
        *
      
      
        FROM
      
       "Test";
    

 

即双引号括起来表名, 大小写必须一致.

这样虽然在 EF 里有了驼峰式, 但是写SQL又成了一大挑战.

 

类型转换

SQLServer 中的类型到.NET中的类型, 基本上都有一个完美的映射, 但是 ORACLE 就不同了. 一堆 Decimal 不说, 连最基本的 bool 都没有原生的映射.

 

要想用 bool 类型, 需要在模型项目的 App.config 中加上一段:

 

      
         1
      
      
        <
      
      
        oracle.manageddataaccess.client
      
      
        >
      
      
         2
      
      
        <
      
      
        version 
      
      
        number
      
      
        ="*"
      
      
        >
      
      
         3
      
      
        <
      
      
        edmMappings
      
      
        >
      
      
         4
      
      
        <
      
      
        edmMapping 
      
      
        dataType
      
      
        ="number"
      
      
        >
      
      
         5
      
      
        <
      
      
        add 
      
      
        name
      
      
        ="bool"
      
      
         precision
      
      
        ="1"
      
      
        />
      
      
         6
      
      
        <
      
      
        add 
      
      
        name
      
      
        ="byte"
      
      
         precision
      
      
        ="2"
      
      
        />
      
      
         7
      
      
        <
      
      
        add 
      
      
        name
      
      
        ="int16"
      
      
         precision
      
      
        ="5"
      
      
        />
      
      
         8
      
      
        </
      
      
        edmMapping
      
      
        >
      
      
         9
      
      
        </
      
      
        edmMappings
      
      
        >
      
      
        10
      
      
        </
      
      
        version
      
      
        >
      
      
        11
      
      
        </
      
      
        oracle.manageddataaccess.client
      
      
        >
      
    

 

 

即:

精度为 1 的 NUMBER 字段,在模型中为 bool 类型

精度为 2 的 NUMBER 字段在模型中为 byte 类型

 

模型属性设置

Oracle + EF5 疑难杂症

 

更新属性方面 :

这个翻译真的很蛋疼. 意向中 这个是用来 更新 诸如 精度修改 等小细节上的, 不过, 我这里把精度从默认的 38 改为 1 , 实体类型还是没有改为 bool, 需要手动更改, 或者把表从模型中删除, 在添加进来.

 

生成时验证 :

假如这个选项为 True, 在你编译的时候, 出现以下情况:

Oracle + EF5 疑难杂症

全部生成成功, 但是有错误. 模型兼容性错误. 这个错误不引响程序的正常运行 , 就是看着有一大堆错误而已.

把这个属性改为 False , 即可以在编译的时候屏蔽这样的错误.

 

TT模板

模型模板

Oracle + EF5 疑难杂症

 

这个结构是将 DbContext 和 实体分成两个不同的DLL, 好处不言而喻.

Model1.tt 是从 XXX.DbContext 下剪切出来的.

Model1.Context.tt 只做了少许修改, 加入了 XXX.DbEntity 的引用, 变化不大.

Model1.tt 中加入了字段注释, Required / StringLength 等, 生成的效果如下:

 

      
         1
      
      
        namespace
      
      
         XXY.DbEntity


      
      
         2
      
      
        {


      
      
         3
      
      
        using
      
      
         System;


      
      
         4
      
      
        using
      
      
         System.Collections.Generic;


      
      
         5
      
      
        using
      
      
         System.Runtime.Serialization;


      
      
         6
      
      
        using
      
      
         System.ComponentModel.DataAnnotations;


      
      
         7
      
      
        using
      
      
         Newtonsoft.Json;


      
      
         8
      
      
         9
      
      
        10
      
      
        ///
      
      
        <summary>
      
      
        11
      
      
        ///
      
      
         承运人运价表


      
      
        12
      
      
        ///
      
      
        </summary>
      
      
        13
      
           [Serializable,DataContract(IsReference = 
      
        true
      
      ),JsonObject(IsReference = 
      
        false
      
      
        )]


      
      
        14
      
      
        public
      
      
        partial
      
      
        class
      
      
         PRICE


      
      
        15
      
      
            {


      
      
        16
      
      
        public
      
      
         PRICE()


      
      
        17
      
      
                {


      
      
        18
      
      
        this
      
      .PRICE_DETAIL = 
      
        new
      
       HashSet<PRICE_DETAIL>
      
        ();


      
      
        19
      
      
                }


      
      
        20
      
      
        21
      
      
        ///
      
      
        <summary>
      
      
        22
      
      
        ///
      
      
         价格流水号  必填项


      
      
        23
      
      
        ///
      
      
        </summary>
      
      
        24
      
      
                [DataMember , Required]


      
      
        25
      
      
        public
      
      
        decimal
      
       PRICE_ID { 
      
        get
      
      ; 
      
        set
      
      
        ; }


      
      
        26
      
      
        27
      
      
        ///
      
      
        <summary>
      
      
        28
      
      
        ///
      
      
         承运人流水号  必填项


      
      
        29
      
      
        ///
      
      
        </summary>
      
      
        30
      
      
                [DataMember , Required]


      
      
        31
      
      
        public
      
      
        decimal
      
       CARRIER_ID { 
      
        get
      
      ; 
      
        set
      
      
        ; }


      
      
        32
      
      
        33
      
      
        ///
      
      
        <summary>
      
      
        34
      
      
        ///
      
      
         承运人代码  必填项


      
      
        35
      
      
        ///
      
      
        </summary>
      
      
        36
      
               [DataMember , Required, StringLength(
      
        30
      
      
        )]


      
      
        37
      
      
        public
      
      
        string
      
       CARRIER_CODE { 
      
        get
      
      ; 
      
        set
      
      
        ; }


      
      
        38
      
      
        39
      
      
        ///
      
      
        <summary>
      
      
        40
      
      
        ///
      
      
         承运人名称  


      
      
        41
      
      
        ///
      
      
        </summary>
      
      
        42
      
               [DataMember, StringLength(
      
        200
      
      
        )]


      
      
        43
      
      
        public
      
      
        string
      
       CARRIER_NAME { 
      
        get
      
      ; 
      
        set
      
      ; }
    

 

 

 

StringLength 读取的是模型中的字段最大长度.

Required 是根据模型中的字段是否可为 Null

Summary 部分:

因为是 Database First, 原本跟据数据生成的模型, 并不会把数据库注释写到模型中, 我写了一个小工具, 后期把注释更新到模型中, 该工具在本文的最下方有提供下载.

 

DataContract IsReference = true 是为了在 WCF 中使用, 而不出现 "循环引用" 的错误.

JsonObject IsReference = false 是为了生成的 Json 不出现 $1 之类的东西.

 

在 Model1.tt 的第 6行:

const string inputFile = @"..\XXX.DbContext\Model1.edmx";

用于指定该模板依赖的 edmx 文件的位置.

SEQUENCE

Oracle 中没有自增长, 只有 SEQUENCE.

看网上有很多文章都是说新建一个触发器, 当插入数的时候, 取一个 SQUENCE 出来.

不是说触发器不好, 我不乐意使用触发器.

这里,我写了一个 TT模板, 从数据库中把所有的当前数据库的 SEQUENCE 名称取出来, 写入到一个枚举中.

 

用法其实就是执行一个SQL语句, 从指定SEQUENCE 中取下一个值.

SELECT XXX.NEXTVAL FROM DUAL

针对这个, 我做了扩展方法:

 

      
        1
      
      
        public
      
      
        static
      
      
        decimal
      
       GetNextVal(
      
        this
      
       System.Data.Entity.DbContext ctx, 
      
        string
      
      
         seqName) {


      
      
        2
      
      
        return
      
       ctx.Database.SqlQuery<
      
        decimal
      
      >(
      
        string
      
      .Format(
      
        "
      
      
        SELECT {0}.NEXTVAL FROM DUAL
      
      
        "
      
      
        , seqName)).First();


      
      
        3
      
      
        }


      
      
        4
      
      
        5
      
      
        public
      
      
        static
      
      
        decimal
      
       GetNextVal<T>(
      
        this
      
       DbContext ctx, T enumValue) 
      
        where
      
       T : 
      
        struct
      
      
        , IComparable, IConvertible, IFormattable {


      
      
        6
      
      
        return
      
      
         ctx.GetNextVal(enumValue.ToString());


      
      
        7
      
       }
    

 

 

使用:

price.PRICE_ID = db.GetNextVal(Sequences.PRICES_SEQ);

 

在 Sequence.ttinclude 文件的 29/30 行

const string ConnectionString = @"Persist Security Info=True;Data Source=192.168.0.3;User ID=BK;password=bk;";

const string SQL = @"SELECT * FROM all_sequences WHERE SEQUENCE_OWNER = ' BK '";

 

ConnectionString 就不用说了, 改成自己的数据库连接字符串.

将 SQL 中的 SEQUENCE_OWNER 改成你的数据库登陆用户(该用户要能看到SEQUENCE)

 

SEQUENCE 模板 和 模型模板在本文的最下方会给出下载地址.

 

大小写敏感的问题

这里说的大小写每感,不同于上面说的表名/字段名大小写的问题.

ORACLE 中,默认的 字段的值 是 大小写敏感 的.

 

搜了一下ORACLE 的忽略大小写的方法, 大部分都是用 UPPER 或是更改会话设置:

alter session set NLS_COMP=LINGUISTIC;

alter session set NLS_SORT=BINARY_CI;

第一种对应到EF 里就是用 ToUpper, 但是这样一来或多或少的影响查询性能.

第二种不方便实现, 且这样改动可能会造成其它方面的问题.

 

用第一种办法,略显繁琐.

我改了一下 模型文件 的模板(Model1.Context.tt), 重载了 ShouldValidateEntity 方法, 在它里面做了一些手脚.

 

      
         1
      
      
        protected
      
      
        override
      
      
        bool
      
      
         ShouldValidateEntity(DbEntityEntry entityEntry) {


      
      
         2
      
      
            UpperConverter.Convert(entityEntry.Entity);


      
      
         3
      
      
        return
      
      
        base
      
      
        .ShouldValidateEntity(entityEntry);


      
      
         4
      
      
        }


      
      
         5
      
      
         6
      
      
        internal
      
      
        static
      
      
        partial
      
      
        class
      
      
         UpperConverter {


      
      
         7
      
      
        private
      
      
        static
      
       Dictionary<Type, List<PropertyInfo>> TPS = 
      
        new
      
       Dictionary<Type, List<PropertyInfo>>
      
        ();


      
      
         8
      
      
        public
      
      
        static
      
      
        void
      
       Add<T>(
      
        params
      
       Expression<Func<T, 
      
        string
      
      >>
      
        [] exprs) {


      
      
         9
      
      
        10
      
      
        foreach
      
       (
      
        var
      
       expr 
      
        in
      
      
         exprs) {


      
      
        11
      
      
        12
      
                       PropertyInfo pi = 
      
        null
      
      
        ;


      
      
        13
      
      
        14
      
      
        switch
      
      
         (expr.Body.NodeType) {


      
      
        15
      
      
        case
      
      
         ExpressionType.MemberAccess:


      
      
        16
      
                               pi =
      
         (PropertyInfo)((MemberExpression)expr.Body).Member;


      
      
        17
      
      
        break
      
      
        ;


      
      
        18
      
      
        default
      
      
        :


      
      
        19
      
      
        throw
      
      
        new
      
      
         InvalidOperationException();


      
      
        20
      
      
                        }


      
      
        21
      
      
        22
      
      
        23
      
      
        if
      
      
         (TPS.ContainsKey(pi.DeclaringType))


      
      
        24
      
      
                            TPS[pi.DeclaringType].Add(pi);


      
      
        25
      
      
        else
      
      
         {


      
      
        26
      
                           TPS.Add(pi.DeclaringType, 
      
        new
      
       List<PropertyInfo>
      
        () { pi });


      
      
        27
      
      
                        }


      
      
        28
      
      
                    }


      
      
        29
      
      
                }


      
      
        30
      
      
        31
      
      
        public
      
      
        static
      
      
        void
      
       Convert(
      
        object
      
      
         obj) {


      
      
        32
      
      
        var
      
       type =
      
         obj.GetType();


      
      
        33
      
      
        if
      
      
         (TPS.ContainsKey(type)) {


      
      
        34
      
      
        var
      
       ps =
      
         TPS[type];


      
      
        35
      
      
        foreach
      
       (
      
        var
      
       p 
      
        in
      
      
         ps) {


      
      
        36
      
      
        var
      
       value = (
      
        string
      
      
        )p.GetValue(obj);


      
      
        37
      
      
        if
      
       (!
      
        string
      
      
        .IsNullOrWhiteSpace(value))


      
      
        38
      
      
                                p.SetValue(obj, value.ToUpper());


      
      
        39
      
      
                        }


      
      
        40
      
      
                    }


      
      
        41
      
      
                }


      
      
        42
      
      
        }


      
      
        43
      
      
        44
      
      
        45
      
      
        internal
      
      
        static
      
      
        partial
      
      
        class
      
      
         UpperConverter {


      
      
        46
      
      
        47
      
      
        public
      
      
        static
      
      
        void
      
      
         Set() {


      
      
        48
      
      
        49
      
      
        #region
      
       审核权限


      
        50
      
                   Add<BOOKING_ORDER_PERMISSIONS>(p => p.CARRIER_CODE, p => p.LOADING_PORT, p => p.ROUTE_CODE, p =>
      
         p.SHIP_CODE,


      
      
        51
      
                       p =>
      
         p.VOYAGE);


      
      
        52
      
                   Add<SPECIAL_PRICE_RULE>(p => p.CARRIER_CODE, p => p.ROUTE_CODE, p => p.SHIP_CODE, p =>
      
         p.VOYAGE);


      
      
        53
      
                   Add<SPECIAL_PRICE_RULE_CONTA>(p =>
      
         p.SIZETYPE_CODE);


      
      
        54
      
      
        #endregion
      
      
        55
      

 

 

这样在 db.SaveChange 的时候, 就会针对 Add<XXX>(…) 中列出的属性做大写转换.

这样一来, 就可以在 EF 中少写很多 ToUpper , 以优化查询性能.

 

事务报错

该部分原来已发过博文: http://www.cnblogs.com/xling/p/3900222.html

这里把它摘录过来:

 

错误:未能加载 Oracle.ManagedDataAccessDTC.dll 或它的依赖项

 

本地WIN7/8.1运行一点问题都没有。打包到 WIN 2008 上,解决了一堆环境问题后,一个大难题出现了:

 

Could not load file or assembly 'Oracle.ManagedDataAccessDTC.dll',什么 PSPManager..ctor 之类的

 

出现这个问题是因为某些地方用了 TransactionScope 。

 

把驱动卸掉,重装了N回,重启了N回,于事无补。

把这个DLL放到 Bin 下,运行网站直接就报错,还是无法加载。

 

Oracle 官方文档中只说不要直接引用这个DTC.dll ,会由 ManagedDataAccess 自动去调用,要区分 32位和64位,其它的基本没提。

 

GOOGLE上、BING上可以搜到几个相关的贴子,但是都是没有结果。度娘就更不用提了。

 

跟据报的那什么 PSPManager..Ctor 用反编译工具查看了一下,跟本就没有那个类。

不过有个 Microsoft.VisualC 的引用。

 

本地GAC (C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualC)下有个11.0.xxx 版本的,

对照那台测试服务器,发现只有个8.XXX的版本。

尝试把本地的考过去,运行结果一样,没有用处。

 

眼看加班都3个半小时了,加上一下午时间,都整了快8个小时,还没整好这玩意,心里急的冒火。

 

顺手搜了一下C++运行库,下了个64位的

 

Microsoft Visual C++ 2010 SP1 Redistributable Package (x64)

http://www.microsoft.com/zh-cn/download/confirmation.aspx?id=13523

 

安装,重启网站,在测试,通过!

 

 

反向伴随类

由于是 Database First , 实体都是自动生成的, 任何手工修改都是无效的. 要想对某个实体的某个属性加个 DataAnnoation , 就需要写一个 Partial 出来.

我没有这样做, 我做了个反向的 伴随类 处理.

 

 

      
         1
      
      
        [AttributeUsage(AttributeTargets.Class)]


      
      
         2
      
      
        public
      
      
        class
      
      
         AnnoationForAttribute : Attribute {


      
      
         3
      
      
        public
      
      
         AnnoationForAttribute(Type type);


      
      
         4
      
      
         5
      
      
        public
      
      
         Type ForType {


      
      
         6
      
      
        get
      
      
        ;


      
      
         7
      
      
        set
      
      
        ;


      
      
         8
      
      
            }


      
      
         9
      
      
        }    


      
      
        10
      
      
        11
      
      
        public
      
      
        class
      
      
         AnnorationHelper {


      
      
        12
      
      
        13
      
      
        public
      
      
        static
      
      
        void
      
      
         AutoMap() {


      
      
        14
      
      
        15
      
      
        var
      
       types = 
      
        typeof
      
      
        (AnnorationHelper).Assembly.GetTypes();


      
      
        16
      
      
        foreach
      
       (
      
        var
      
       t 
      
        in
      
      
         types) {


      
      
        17
      
      
        var
      
       attr = (AnnoationForAttribute)t.GetCustomAttributes(
      
        typeof
      
      (AnnoationForAttribute), 
      
        false
      
      
        ).FirstOrDefault();


      
      
        18
      
      
        if
      
       (attr != 
      
        null
      
      
        )


      
      
        19
      
                       TypeDescriptor.AddProviderTransparent(
      
        new
      
      
         AssociatedMetadataTypeTypeDescriptionProvider(attr.ForType, t), attr.ForType);


      
      
        20
      
      
                }


      
      
        21
      
      
        22
      
      
            }


      
      
        23
      
      
        24
      
       }  
    

 

 

反向伴随类的声明:

 

      
        1
      
       [AnnoationFor(
      
        typeof
      
      
        (DbEntity.PRICE))]


      
      
        2
      
      
        public
      
      
        class
      
      
         PRICE {


      
      
        3
      
      
        4
      
           [CompareWith(
      
        "
      
      
        EFFECTIVE_DATE
      
      
        "
      
      
        , CompareWithOpts.Gt)]


      
      
        5
      
      
        public
      
      
        object
      
      
         EXPIRATION_DATE {


      
      
        6
      
      
        get
      
      
        ;


      
      
        7
      
      
        set
      
      
        ;


      
      
        8
      
      
            }


      
      
        9
      
       }
    

 

 

现在, 只需要在 Global 里调用:

      AnnorationHelper.AutoMap();
    

 

即可把反向伴随类注册到实体类上.

 

OracleFunction ?

使用 SqlServer + EF , 可以用 SqlFunctions, 但是Oracle 并没有提供类似的功能.

Oracle 的函数到 LINQ 的函数映射可以参考:

http://docs.oracle.com/cd/E11882_01/win.112/e23174/canonical_map.htm#ODPNT7777

文档中说会把 concat 转化为 "xx"||"xx" 或 CONCAT 方法的调用, 但是在实际中, 却无法将 STRING 和 DECIMAL 用 String.Concat 连接起来.

 

为了一个特殊业务, 我在这个地方耗了好几个小时, 没有办法, 只能通过自定义函数解决了.

  

      
        1
      
      
        CREATE
      
      
        OR
      
      
        REPLACE
      
      
        function
      
       BK.ToString(P 
      
        NUMBER
      
      
        ) 


      
      
        2
      
      
        return
      
      
        VARCHAR
      
      
        3
      
      
        is
      
      
        4
      
          V 
      
        VARCHAR
      
      (
      
        10
      
      
        ); 


      
      
        5
      
      
        begin
      
      
        6
      
      
        select
      
       TO_CHAR(P) 
      
        into
      
       V 
      
        FROM
      
      
         DUAL; 


      
      
        7
      
      
        return
      
      
         V; 


      
      
        8
      
      
        end
      
      ;
    

 

然后更新模型, 将函数添加到模型中.

定义一个 FUNCTION 的映射.

  

      
        1
      
      
        public
      
      
        static
      
      
        class
      
      
         OracleFunctions {


      
      
        2
      
           [EdmFunction(
      
        "
      
      
        Model.Store
      
      
        "
      
      , 
      
        "
      
      
        TOSTRING
      
      
        "
      
      
        )]


      
      
        3
      
      
        public
      
      
        static
      
      
        string
      
       ToString(
      
        decimal
      
      
         d) {


      
      
        4
      
      
        throw
      
      
        new
      
       InvalidOperationException(
      
        "
      
      
        Not to be called from client code
      
      
        "
      
      
        );


      
      
        5
      
      
            }


      
      
        6
      
       }
    

Model.Store 和模型的命名空间一样(未验证不一样是否可以)

然后 在LINQ TO SQL 中 用 拼接字符串的方法使用 :

let tmp = sp.PORT_CODE.ToUpper() + "," + OracleFunctions.ToString(s.COURSE)

 

很简单的一个功能, 搞的很蛋疼.

 

文中所述的下载地址:

http://files.cnblogs.com/xling/OracleEF.7z

 

 

捧个场, 推个贱。

Oracle + EF5 疑难杂症


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论