日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Oracle + EF5 疑難雜癥

系統(tǒng) 2156 0
原文: Oracle + EF5 疑難雜癥

PDF 版

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

Oracle 環(huán)境準(zhǔn)備

ODAC

ODAC 全稱 Oracle Data Access Components

下載:

?

ODTWthODAC 是用于VS的開發(fā)工具.

?

安裝

采用ODAC XCopy 版, 就不需要安裝體積龐大的 Oracle Client 了.

  1. 將 ODAC 解壓到一個(gè)固定的位置, 比如 C:\ODAC , 注意, 這個(gè)文件夾用完后不能刪除
  2. 以管理員身份打開一個(gè) CMD
  3. Cd C:\ODAC\ODP.NET\Managed\X64
  4. 運(yùn)行 configure.bat ( 不要圖快,直接右鍵以管理員身份運(yùn)行, 沒用! )

    Oracle + EF5 疑難雜癥

  5. 運(yùn)行成功后, 會(huì)注冊(cè)相關(guān)DLL到GAC中.
  6. 打開 Machine.config (C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config)

    可以看到加入了一個(gè) setion oracle.manageddataaccess.client,

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

    對(duì)應(yīng) section oracle.manageddataaccess.client 還有一個(gè)配置:

              
                 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 即別名, 不區(qū)分大小寫

    HOST 即 ORACLE 服務(wù)器地址

    PORT 為指定的監(jiān)聽端口

    SERVICE_NAME 即ORACLE 實(shí)例名

    ?

    如果需要 32位的, 可以重復(fù)上面的步驟, 不過運(yùn)行的是 X86目錄下面的 configure.bat 而已.

    ?

    ODTWithODAC 一路 NEXT 即可.

    在 VS 中連接數(shù)據(jù)庫, 即可看到多出一個(gè) ODP.NET 托管驅(qū)動(dòng)程序選項(xiàng):

    Oracle + EF5 疑難雜癥

    用TNS 測(cè)試連接:

    Oracle + EF5 疑難雜癥

    注意: 這里的 Tnsnames.ora 的位置, 不是上面步驟中的位置 . 如果文件不存在, 請(qǐng)?jiān)?COPY一個(gè)到 admin 目錄下.

    ?

    用 EZ 測(cè)試連接:

    Oracle + EF5 疑難雜癥

網(wǎng)站運(yùn)行可能出現(xiàn)的錯(cuò)誤:

無法讀取配置節(jié) Oracle.manageddataaccess.client 因?yàn)樗鄙俟?jié)聲明

請(qǐng)檢查你的應(yīng)用程序池
Oracle + EF5 疑難雜癥

A, 如果 "啟用32位應(yīng)用程序"為 True , 請(qǐng)改為 False , 因?yàn)橹话惭b了 64 位的 ODAC

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

?

Entity Framework

支持

當(dāng)前EF6 不支持 Oracle, 而且只能是 Database First .

表名/字段名 大小寫的問題

在Oracle 中建的表, 在更新模型的時(shí)候, 全是大寫, 表字段也全是大寫:

Oracle + EF5 疑難雜癥

?

這個(gè)問題對(duì)于習(xí)慣于 SQLServer 的你來說, 感覺一定是吹鼻子瞪眼,抓狂的想辦法把表名變小寫.

有辦法變小寫, 不過,了解了因果之后, 你一定會(huì)想:大寫就大寫吧.

?

建表語句 中的 表名/列名 用雙引號(hào)括起來 :

      
        1
      
      
        CREATE
      
      
        TABLE
      
      
         BK."Test"


      
      
        2
      
      
        (


      
      
        3
      
           "ID" 
      
        NUMBER
      
      
        NOT
      
      
        NULL
      
      
        ,


      
      
        4
      
           "Name" 
      
        NUMBER
      
      
        NOT
      
      
        NULL
      
      
        5
      
       )
    

?

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

Oracle + EF5 疑難雜癥

但是:

Oracle + EF5 疑難雜癥

必須用

      
        SELECT
      
      
        *
      
      
        FROM
      
       "Test";
    

?

即雙引號(hào)括起來表名, 大小寫必須一致.

這樣雖然在 EF 里有了駝峰式, 但是寫SQL又成了一大挑戰(zhàn).

?

類型轉(zhuǎn)換

SQLServer 中的類型到.NET中的類型, 基本上都有一個(gè)完美的映射, 但是 ORACLE 就不同了. 一堆 Decimal 不說, 連最基本的 bool 都沒有原生的映射.

?

要想用 bool 類型, 需要在模型項(xiàng)目的 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 類型

?

模型屬性設(shè)置

Oracle + EF5 疑難雜癥

?

更新屬性方面 :

這個(gè)翻譯真的很蛋疼. 意向中 這個(gè)是用來 更新 諸如 精度修改 等小細(xì)節(jié)上的, 不過, 我這里把精度從默認(rèn)的 38 改為 1 , 實(shí)體類型還是沒有改為 bool, 需要手動(dòng)更改, 或者把表從模型中刪除, 在添加進(jìn)來.

?

生成時(shí)驗(yàn)證 :

假如這個(gè)選項(xiàng)為 True, 在你編譯的時(shí)候, 出現(xiàn)以下情況:

Oracle + EF5 疑難雜癥

全部生成成功, 但是有錯(cuò)誤. 模型兼容性錯(cuò)誤. 這個(gè)錯(cuò)誤不引響程序的正常運(yùn)行 , 就是看著有一大堆錯(cuò)誤而已.

把這個(gè)屬性改為 False , 即可以在編譯的時(shí)候屏蔽這樣的錯(cuò)誤.

?

TT模板

模型模板

Oracle + EF5 疑難雜癥

?

這個(gè)結(jié)構(gòu)是將 DbContext 和 實(shí)體分成兩個(gè)不同的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
      
      
        ///
      
      
         承運(yùn)人運(yùn)價(jià)表


      
      
        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
      
      
        ///
      
      
         價(jià)格流水號(hào)  必填項(xiàng)


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


      
      
        25
      
      
        public
      
      
        decimal
      
       PRICE_ID { 
      
        get
      
      ; 
      
        set
      
      
        ; }


      
      
        26
      
      
        27
      
      
        ///
      
      
        <summary>
      
      
        28
      
      
        ///
      
      
         承運(yùn)人流水號(hào)  必填項(xiàng)


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


      
      
        31
      
      
        public
      
      
        decimal
      
       CARRIER_ID { 
      
        get
      
      ; 
      
        set
      
      
        ; }


      
      
        32
      
      
        33
      
      
        ///
      
      
        <summary>
      
      
        34
      
      
        ///
      
      
         承運(yùn)人代碼  必填項(xiàng)


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


      
      
        37
      
      
        public
      
      
        string
      
       CARRIER_CODE { 
      
        get
      
      ; 
      
        set
      
      
        ; }


      
      
        38
      
      
        39
      
      
        ///
      
      
        <summary>
      
      
        40
      
      
        ///
      
      
         承運(yùn)人名稱  


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


      
      
        43
      
      
        public
      
      
        string
      
       CARRIER_NAME { 
      
        get
      
      ; 
      
        set
      
      ; }
    

?

?

?

StringLength 讀取的是模型中的字段最大長(zhǎng)度.

Required 是根據(jù)模型中的字段是否可為 Null

Summary 部分:

因?yàn)槭?Database First, 原本跟據(jù)數(shù)據(jù)生成的模型, 并不會(huì)把數(shù)據(jù)庫注釋寫到模型中, 我寫了一個(gè)小工具, 后期把注釋更新到模型中, 該工具在本文的最下方有提供下載.

?

DataContract IsReference = true 是為了在 WCF 中使用, 而不出現(xiàn) "循環(huán)引用" 的錯(cuò)誤.

JsonObject IsReference = false 是為了生成的 Json 不出現(xiàn) $1 之類的東西.

?

在 Model1.tt 的第 6行:

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

用于指定該模板依賴的 edmx 文件的位置.

SEQUENCE

Oracle 中沒有自增長(zhǎng), 只有 SEQUENCE.

看網(wǎng)上有很多文章都是說新建一個(gè)觸發(fā)器, 當(dāng)插入數(shù)的時(shí)候, 取一個(gè) SQUENCE 出來.

不是說觸發(fā)器不好, 我不樂意使用觸發(fā)器.

這里,我寫了一個(gè) TT模板, 從數(shù)據(jù)庫中把所有的當(dāng)前數(shù)據(jù)庫的 SEQUENCE 名稱取出來, 寫入到一個(gè)枚舉中.

?

用法其實(shí)就是執(zhí)行一個(gè)SQL語句, 從指定SEQUENCE 中取下一個(gè)值.

SELECT XXX.NEXTVAL FROM DUAL

針對(duì)這個(gè), 我做了擴(kuò)展方法:

?

      
        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 就不用說了, 改成自己的數(shù)據(jù)庫連接字符串.

將 SQL 中的 SEQUENCE_OWNER 改成你的數(shù)據(jù)庫登陸用戶(該用戶要能看到SEQUENCE)

?

SEQUENCE 模板 和 模型模板在本文的最下方會(huì)給出下載地址.

?

大小寫敏感的問題

這里說的大小寫每感,不同于上面說的表名/字段名大小寫的問題.

ORACLE 中,默認(rèn)的 字段的值 是 大小寫敏感 的.

?

搜了一下ORACLE 的忽略大小寫的方法, 大部分都是用 UPPER 或是更改會(huì)話設(shè)置:

alter session set NLS_COMP=LINGUISTIC;

alter session set NLS_SORT=BINARY_CI;

第一種對(duì)應(yīng)到EF 里就是用 ToUpper, 但是這樣一來或多或少的影響查詢性能.

第二種不方便實(shí)現(xiàn), 且這樣改動(dòng)可能會(huì)造成其它方面的問題.

?

用第一種辦法,略顯繁瑣.

我改了一下 模型文件 的模板(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
      
       審核權(quán)限


      
        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 的時(shí)候, 就會(huì)針對(duì) Add<XXX>(…) 中列出的屬性做大寫轉(zhuǎn)換.

這樣一來, 就可以在 EF 中少寫很多 ToUpper , 以優(yōu)化查詢性能.

?

事務(wù)報(bào)錯(cuò)

該部分原來已發(fā)過博文: http://www.cnblogs.com/xling/p/3900222.html

這里把它摘錄過來:

?

錯(cuò)誤:未能加載 Oracle.ManagedDataAccessDTC.dll 或它的依賴項(xiàng)

?

本地WIN7/8.1運(yùn)行一點(diǎn)問題都沒有。打包到 WIN 2008 上,解決了一堆環(huán)境問題后,一個(gè)大難題出現(xiàn)了:

?

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

?

出現(xiàn)這個(gè)問題是因?yàn)槟承┑胤接昧?TransactionScope 。

?

把驅(qū)動(dòng)卸掉,重裝了N回,重啟了N回,于事無補(bǔ)。

把這個(gè)DLL放到 Bin 下,運(yùn)行網(wǎng)站直接就報(bào)錯(cuò),還是無法加載。

?

Oracle 官方文檔中只說不要直接引用這個(gè)DTC.dll ,會(huì)由 ManagedDataAccess 自動(dòng)去調(diào)用,要區(qū)分 32位和64位,其它的基本沒提。

?

GOOGLE上、BING上可以搜到幾個(gè)相關(guān)的貼子,但是都是沒有結(jié)果。度娘就更不用提了。

?

跟據(jù)報(bào)的那什么 PSPManager..Ctor 用反編譯工具查看了一下,跟本就沒有那個(gè)類。

不過有個(gè) Microsoft.VisualC 的引用。

?

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

對(duì)照那臺(tái)測(cè)試服務(wù)器,發(fā)現(xiàn)只有個(gè)8.XXX的版本。

嘗試把本地的考過去,運(yùn)行結(jié)果一樣,沒有用處。

?

眼看加班都3個(gè)半小時(shí)了,加上一下午時(shí)間,都整了快8個(gè)小時(shí),還沒整好這玩意,心里急的冒火。

?

順手搜了一下C++運(yùn)行庫,下了個(gè)64位的

?

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

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

?

安裝,重啟網(wǎng)站,在測(cè)試,通過!

?

?

反向伴隨類

由于是 Database First , 實(shí)體都是自動(dòng)生成的, 任何手工修改都是無效的. 要想對(duì)某個(gè)實(shí)體的某個(gè)屬性加個(gè) DataAnnoation , 就需要寫一個(gè) Partial 出來.

我沒有這樣做, 我做了個(gè)反向的 伴隨類 處理.

?

?

      
         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
      
       }
    

?

?

現(xiàn)在, 只需要在 Global 里調(diào)用:

      AnnorationHelper.AutoMap();
    

?

即可把反向伴隨類注冊(cè)到實(shí)體類上.

?

OracleFunction ?

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

Oracle 的函數(shù)到 LINQ 的函數(shù)映射可以參考:

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

文檔中說會(huì)把 concat 轉(zhuǎn)化為 "xx"||"xx" 或 CONCAT 方法的調(diào)用, 但是在實(shí)際中, 卻無法將 STRING 和 DECIMAL 用 String.Concat 連接起來.

?

為了一個(gè)特殊業(yè)務(wù), 我在這個(gè)地方耗了好幾個(gè)小時(shí), 沒有辦法, 只能通過自定義函數(shù)解決了.

??

      
        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
      
      ;
    

?

然后更新模型, 將函數(shù)添加到模型中.

定義一個(gè) 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 和模型的命名空間一樣(未驗(yàn)證不一樣是否可以)

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

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

?

很簡(jiǎn)單的一個(gè)功能, 搞的很蛋疼.

?

文中所述的下載地址:

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

?

?

捧個(gè)場(chǎng), 推個(gè)賤。

Oracle + EF5 疑難雜癥


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 新龙县| 建始县| 汶上县| 洛扎县| 安福县| 沭阳县| 华亭县| 金阳县| 上林县| 区。| 永泰县| 进贤县| 斗六市| 麻栗坡县| 福贡县| 区。| 大城县| 黄山市| 雅安市| 甘南县| 武山县| 湖北省| 酒泉市| 苗栗市| 明水县| 永宁县| 开远市| 邮箱| 赤峰市| 禹城市| 德州市| 长丰县| 桦川县| 连山| 玉山县| 探索| 荔波县| 临清市| 裕民县| 鱼台县| 东台市|