none
請教 Entity Framework 的 Master – Detail FK 的設定問題 RRS feed

  • 問題

  • 原本資料庫設計是

    DB Schema 分別是  Master – DetailA – DetailB 的架構

    其 Detail A 裡有記錄 Master 的 id ,Detail B 有記錄 Detail B 的 id

    因為這是一定要有的值,所以我索性加上了 Not null 

    edmx 那裡重新整理後,再重新編譯!就會出現以下的錯誤????


    一開始還沒有意識到是 not null  的關係!花了好久的時間之後才找到
    只把 not 拿掉後就又一切正常,不知是否知道其原因呢?因為這樣子的情況加上 not null 是確保 Master 和 detail 之間的資料關係性

    感恩~~

    錯誤    1    錯誤 3023: 對應片段中從第 1153, 1267, 1294, 1321, 1339, 1357, 1374 行開始有問題: 資料行 WorkDetail.WorkID 沒有預設值而且不可為 Null。必須有資料行值才能儲存實體資料。
    有下列狀況時將不會反覆存取索引鍵為 (PK) 的實體:
      ((PK 是在 'WorkDetail' EntitySet 中

    OR PK 在 AssociationSet 'WorkDetail_FK_PriceCustomID' 中扮演 Role 'WorkDetail'

     OR PK 在 AssociationSet 'WorkDetail_FK_PricePaperID' 中扮演 Role 'WorkDetail'

     OR PK 在 AssociationSet 'WordDetail_FK_PricePrintID' 中扮演 Role 'WorkDetail'

     OR PK 在 AssociationSet 'WorkDetail_FK_SpecTypeID' 中扮演 Role 'WorkDetail'

    OR PK 在 AssociationSet 'WorkDetail_FK_WorkID' 中扮演 Role 'WorkDetail'

    OR PK 在 AssociationSet 'WorkDetail_FK_PriceBindID' 中扮演 Role 'WorkDetail')

    AND (PK 不在 'WorkDetail' EntitySet 中

    OR PK 在 AssociationSet 'WorkDetail_FK_WorkID' 中不是扮演 Role 'WorkDetail'))

    • 已移動 小朱MVP, Moderator 2009年6月4日 上午 10:47 ([Loc]From:Visual Studio一般討論區(General))
    2009年6月4日 上午 10:26

解答

  • 重新驗證其內容後

    當在 FK 的欄位上設定為 not null 後,其 SSDL 中會加上 Nullable = false

    CSDL 中的關聯中卻會將 Multiplicity 強制改成 1  (原本應該是 0..1)

    很神奇的是!

    在 edmx 的畫面上卻還是 0..1  , 但背後的 xml 卻已經不一樣了。  ( 難怪之前一直看不出來 orz )

    另外,在 CSDL 的關聯定義是「雙向驗證」

    即使我好心把關聯改回成 0..1 就會出現 edmx 的驗證無法通過的錯誤


    這個怎麼看都很像是在關聯式的欄位判斷上出現了問題

    目前小弟的結論是 FK 的欄位暫先不要加上 not null 的作法,以維持關聯的正確性

    • 已標示為解答 Franma 2009年6月9日 上午 08:29
    2009年6月9日 上午 08:28

所有回覆

  • 內建的EDM tools目前有很多問題,常常會發生更新資料庫對應後造成錯亂.因為內建工具目前反映資料庫異動的功能存在很多問題(我認為很難解決).
    所以你有兩種方式解決此問題
    1.手動編輯修改現有的EDM File,當然你要了解其中的關係.
    2.直接砍掉從新由資料庫從拉一次.

    由衷建議你研究EF的MSL CSDL SSDL的規則,自行撰寫包含程式,不要用內建工具處理,你會發現EF中原來不單單只是工具表上的那些東西而已.
    2009年6月5日 上午 07:30


  • 第二種方式已經有試過了,但結果還是一樣。

    至於MSL、CSDL 和 SSDL 這三個區塊也都有去看過了,在設定上是沒有什麼太大的問題

    反倒是 自動產生的程式,還沒有逐一去看  ( 都忘了這點 )

    稍後再用程式碼比對的方式去查一下差異好了!


    感謝大大的建議呀!

    目前的作法就是暫時先把 not 的部分拿掉!先讓程式可以正常執行。 

    雖然我覺得這個做法實在是太瞎了,在還沒有真正找到問題前就只好先忍著

    2009年6月6日 上午 08:44
  • 重新驗證其內容後

    當在 FK 的欄位上設定為 not null 後,其 SSDL 中會加上 Nullable = false

    CSDL 中的關聯中卻會將 Multiplicity 強制改成 1  (原本應該是 0..1)

    很神奇的是!

    在 edmx 的畫面上卻還是 0..1  , 但背後的 xml 卻已經不一樣了。  ( 難怪之前一直看不出來 orz )

    另外,在 CSDL 的關聯定義是「雙向驗證」

    即使我好心把關聯改回成 0..1 就會出現 edmx 的驗證無法通過的錯誤


    這個怎麼看都很像是在關聯式的欄位判斷上出現了問題

    目前小弟的結論是 FK 的欄位暫先不要加上 not null 的作法,以維持關聯的正確性

    • 已標示為解答 Franma 2009年6月9日 上午 08:29
    2009年6月9日 上午 08:28
  • 是的
    所以上面我回覆不要使用內建工具的原因
    就是因為目前內建工具問題很多.
    目前我本身從Code到定義檔都自行手動產生.
    雖然麻煩,但出現問題也好處理,另外有很多工具無法達成的功能也能實現.

    另外
    EF 4.0即將與dotNet Framework 4.0一起推出了.
    如果不使用工具會發現改變其實並不大.
    唯一最巨大的改變應該是CO/PO的Support,但初步看了一些文件發現EF Support的模式等於讓人二選一....XX.
    但起來此需求是為了Ado.net Data service這些跨AP間傳輸的一些問題所衍生的解決方案.
    2009年6月9日 上午 08:34
  • 所以您的 SSDL 和 CSDL 就沒有這方面的問題?? 也完全不會去驗證這層關係嚕??

    因為小弟改完後 xml 就會標示出 關聯的部分出錯 (藍色的蚯引線)



    本來是想說能不用手動就盡量可以省一點時間!  看樣子目前是有一好沒兩好!XDDDD

    若是要自已打造的話~~~   主要是因為太懶了! 囧~~~  ( 所以不能怪別人 )

    頂多就是再 外掛自已的程式碼而已

    晚一點再把我的專案拿到 vs 2010 上面試試看好了




    ps..   說到 EF 2  小弟看到的效果是完全沒有用到 edmx ,很神奇~~~~   很懷疑 沒有 SSDL , CSDL ,程式怎麼去 intellisense ??

    2009年6月9日 上午 08:51
  • 我目前完全不用工具,也就是沒有任何的.edm檔.
    原來EDM內的CSDL,SSDL,MSL區塊我分成三個檔案.
    然後手動建立Context Class與所有的Entity Class.
    簡單說就是完全的手動處理.

    EF4(跳號了不是2),我試用VS2010 beta1 EDM工具差異並不大,問題還是一堆,看起來沒甚麼改善,除了多支援複雜型別...(但這不是目前工具問題的重點呀....希望未來還會繼續加強),最大的差異是新的EF工具改為由Modal先建再產生Database,而非Modal由database產生,這個從1.0 CPT時就被一堆人詬病的問題,EF終於從善如流.(正規的設計邏輯的確應該這樣,但如果要偏向普及化EF1.0的方式比較正確,但問題是EF是ORM產品,是一個基礎,不是一個工具...).
    另外COPO這部分屬於比較大的改變,需要好好研究.

    2009年6月9日 上午 09:13
  • 雖然文件上有說可以自行建立

    但維護成本會不會太高??  基本上是覺得  EDM 的驗證規則有爭議,不然小弟是覺得很方便。

    值得我們全部自行建立 CSDL , SSDL , MSL 和 Context , Enitity 嗎?? ( 小弟想到的做法是 先用 EDM 建置完後再手動拆解,反正 DB 會越來越穩定 )



    對喔 EF 4 跟 WPF 4 一樣了  ( 跳很大 )  

    剩下的等小弟下去試過後再跟您討論好了 ^^  

    2009年6月10日 上午 05:34
  • 的確
    手動建立的成本很高
    不論是所耗用時間或是技術的層次
    工具雖然方便,但不幸的目前的EDM Tools只能做到約30%左右的EF功能(不誇大).
    如果沒錯,你之前應該沒有用過任何的ORM Framework與實際專案上,EF這類ORM Framework最終再使用你會發現還是必須要了解底層運作,因為目前所有的ORM Framework尚無法很完整的將整個DataAccess部分給完美的封裝,導致在某些情況下必須透過改寫一些Framework架構來達成不同的需求.當你越深入使用EF你遇到的問題會更多,你會發現不研究底層很多功能無法達成,至少我有幾個同事搞到最後都放棄了,因為透過EF而不修改或了解底層運作很多功能無法達成.

    而EF用手動建立能做到的需求非常之多.
    舉下列子目前在EF1.0只能手動處理的
    1.複雜型別建立
    2.SSDL用SQL語法定義來源,而非是指定View或Table
    3.巢狀式資料結構 (譬如說會計科目的階層)
    4.定義檔分散在不同的檔案(目前1.0只Support SSDL)
    5.Entity Class需要獨立成個別class file.
    ....還有很多.

    但除此之外我手動的目的主要原因並非只是上述的原因,最腫要的原因目前EF對於Lazy loading並不支援自動延遲載入功能,預設必須靠IsLoad由程式中來判斷並手動載入,網路上有更好的解決方式,但很多底層的class必須修改,所以會導致原工具無法搭配.
    此外如果有做分層架構你將會遇到動態查詢的問題,也會需要修改底層架構,我之前所發的一篇LINQ Creation就是為了解決此問題所製做的class,大多情況下針對查詢的where語句動態問題都已解決(包含Lambda的序列化),有興趣可以參考看看.

    2009年6月10日 上午 08:05
  • 感謝您的經驗談呀!   受益了~~~

    的確,之前的案子是沒有導入過相關的 ORM Framework   

    主要是因為 DAL + DTO 已經可滿足需求啦! (搭配 attribute ) 

    自已寫相關的機制 



    這次在用 EF 導入在專案時,的確有遇到您講的一些情況

    但為了不要變得太複雜,所以就以  EF ( 含一些擴充 )  + Enterprise lib 4 的方式去改寫   ( 覺得有不倫不類的 ) 哈哈~~

    而且,Linq 的查詢語法在 ref table 會顯得不夠直覺,最後較困難的還是改用 SQL 來查詢  ( 說實在的 某些由 Linq 產生出來的 sql 語法,我還要花時間去驗證是不是我想的,這個就花我超多時間的。 )

    Linq Createion 收藏起來 ^^ 感恩!


    2009年6月17日 上午 05:38
  • 另外再提供一個經驗,在這幾年想通的問題

    以前我曾經對於使用ORM後會失去一些SQL Query彈性的問題很困擾,譬如說報表.
    很多人不清楚一件事,使用ORM如果不用OO(物件導向)模式來開發,不如不要使用.
    並且如果專案使用 ORM來封裝DAL,那就最好全部使用ORM來存取,不應該再採用其他方式,因為這樣做產生的問題比解決的問題更多.
    但如上述報表這樣東西目前所有的ORM皆無法處理,即使是EF配合LINQ.

    對此研究過很多專案與網路上的資源,我發現一件事,報表與運作應該要切割,也就是說
    一個應用程式ORM應當配合OO(物件導向)來完成大多數功能,但報表部分應該獨立出後再想方式整合至UI上.

    譬如我最近為了資料量過大統計的問題搞了資料倉儲來處理報表問題,但目前沒有任何ORM Support資料倉儲這塊(也幾乎不可能).
    所以報表這類程式因為種種原因不應當用ORM來做資料存取.
    2009年6月17日 上午 06:25