2014-09-22 20 views
2

在數據庫中,我們不允許做出了巨大的變化,我們有如下表其他表中(不相關的列隱藏在[一些列...]):實體框架6 - 引用表 - 如何編寫自定義naviagtion-property-logic?

Id, [some other columns...] 

表1

Id, [some other columns...] 

表2

Id, [some other columns...] 

參考

Id, MasterId, TableName, ForeignId 

我們使用EF6(代碼首先,數據註解優選)來訪問數據庫。

現在我們希望能夠在我們的代碼中導航,例如通過「master.References.First()。ReferenceRow」引用表。在這種情況下,「ReferenceRow」可能是一個導航屬性,我們需要在「映射」後面放置一些額外的定製邏輯,如「查看值TableName,如果Table1從表中取出行1其中Id = ForeignId,否則,如果表2 ...「列表名將像TPH中的鑑別器列。我認爲EF中沒有開箱即用的解決方案,但是可以將此邏輯添加到導航屬性中嗎?

當然,我們可以創建一個抽象類「RefereceTable」,讓所有可引用的表繼承它。但在這種情況下,TPH會創造出很多專欄。 TPC和TPT不會給我們我們想要的表現。這就是爲什麼我們不能使用繼承類型來解決這個問題的原因。此外,該表中唯一的常見列將是Id列。

這就是我們想要知道的原因:有沒有一種方法可以在導航屬性後面實現可以解決我們問題的自定義邏輯?

+0

這種邏輯不應該在導航屬性中。它屬於資源庫層的某個地方。所以像GetReferencesByMasterId(int masterId)這樣的函數可以讓代碼查看不同的導航屬性。 – tranceporter 2014-09-22 09:37:14

+0

@tranceporter是的,那是正確的,那就是我們的實際情況,它可以讀取。但是對於插入,我們有一些問題:可以說我們想要在Master中插入一行,在Table1中插入一行,在References中插入一行,將其他鏈接在一起。在保存之前我們不知道Table1-Row的Id,所以我們必須再次調用SaveChanges()來保存References-row。這將導致第二筆交易。面對這個問題,引起了我對上述問題的關注。 – Greenhorn 2014-09-22 10:23:10

+0

看看我的回答是否有幫助。 – tranceporter 2014-09-22 10:37:27

回答

0

根據您的評論,您無需擔心Table1-Row的Id。英孚將爲您處理。您只需構建實體層次結構並調用SaveChanges一次即可。

var master = _context.Master.Create(); 
master.property1 = "xyz"; 

var table1Row = _context.Table1.Create(); 
table1Row.property1 = "abc"; 

var referenceRow1 = _context.Reference.Create(); 
referenceRow1.MasterId = master.Id; 
referenceRow.TableRow1Id = table1Row.Id; 

_context.SaveChanges(); 

沿着這些方向的東西應該做你正在努力實現的。

+0

看來這不起作用,因爲References.ForeignId沒有被聲明爲某個表的外鍵。它沒有參考,因爲我們無法知道巫婆桌上它會在設計時參考。設置masterId工作正常,但ForeignId的值爲0.任何其他想法? – Greenhorn 2014-09-22 12:07:26

+0

在這種情況下,而不是有一個單一的ForeignId列,我會有多個列像Table1Id,Table2Id,並擺脫TableName列。這樣您可以創建外鍵,然後將檢查約束放在Table1Id和Table2Id上(如果需要)。 (如Table1Id爲null && Table2Id爲null是無效的,可以通過檢查約束捕獲)。海事組織是一個更好的數據庫設計,並將確保更好的數據完整性 – tranceporter 2014-09-22 12:51:26

+0

像這樣改變數據庫設計,對於我們的應用程序來說可以很好地工作。但是還有其他應用程序使用該數據庫,所以如果沒有其他應用程序的大量工作,這是不可能的。肯定會有效,但這不是我們想要的...抱歉... – Greenhorn 2014-09-24 14:05:29