在 Entity Framewrok 中使用View要注意的小事情
最近在寫程式時,原本一切都很順利。Build都Build的過,也沒出現任何錯誤。
但卻發現顯示的資料一直不正確,回頭去找有沒有邏輯錯誤的地方,也都沒有發現
意外的讓我發現了一個容易疏忽的小地方....
首先打開edmx來看看拉進來的Table結構
再來看看資料庫中所拉的View的語法
除了資料表沒有正規化之外,似乎一切都很正常
寫一個非常簡單的Code把View的資料撈出來看看...
MyEntities db = new MyEntities();
var model = db.View_郵遞區號道路.Take(100);
foreach (var item in model)
{
Console.WriteLine(item.縣市 + item.鄉鎮市區 + item.路名);
}
Console.ReadKey();
結果:
撈回來的資料全都一樣
Why? Why? Why?
原因就在拉出來的View沒有 PrimaryKey(主索引鍵)
在Entity中,所有實體型別都必須要有個主鍵 ( 如果用LINQ To SQL 就不需要,因為原理不太一樣 )
一般在拉 Table 到 edmx 中的時候,沒有主鍵是沒辦法拉進來的,會出現下面的訊息並排除
但如果是View的話,Entity會自動幫你判斷主索引鍵
但如果他判斷出來的不是唯一的索引鍵,就會發生上面的窘境。
解決辦法就是在拉View的時候,加入階層最頂層的主索引鍵(也就是不會重複)
要是真的沒辦法,用 newid() 或是 row_number() 建一個假的欄位當PK 也是可以的。
(只是這樣要在edmx裡面將新加的欄位設為主索引鍵)
改View如下
ALTER VIEW [dbo].[View_郵遞區號道路]
AS
SELECT
ROW_NUMBER() OVER(ORDER BY dbo.郵遞區號.縣市) as "假PK",
dbo.郵遞區號.縣市,
dbo.郵遞區號.鄉鎮市區,
dbo.郵遞區號.郵遞區號,
dbo.郵遞區號_道路.路名
FROM
dbo.郵遞區號_道路 INNER JOIN dbo.郵遞區號
ON dbo.郵遞區號_道路.郵遞區號 = dbo.郵遞區號.郵遞區號
然後edmx更新後,自己選擇PK
在搜尋一次,結果就會對了。