在 Entity Framewrok 中使用View要注意的小事情

在 Entity Framewrok 中使用View要注意的小事情

最近在寫程式時,原本一切都很順利。Build都Build的過,也沒出現任何錯誤。

但卻發現顯示的資料一直不正確,回頭去找有沒有邏輯錯誤的地方,也都沒有發現

意外的讓我發現了一個容易疏忽的小地方....

 

首先打開edmx來看看拉進來的Table結構

2011-01-06_235351

再來看看資料庫中所拉的View的語法

2011-01-06_235603

image

 

 

除了資料表沒有正規化之外,似乎一切都很正常

寫一個非常簡單的Code把View的資料撈出來看看...

	MyEntities db = new MyEntities();

var model = db.View_郵遞區號道路.Take(100);

foreach (var item in model)
{
      Console.WriteLine(item.縣市 + item.鄉鎮市區 + item.路名);
}

Console.ReadKey();

結果:

image

撈回來的資料全都一樣

 

Why? Why? Why?

 

原因就在拉出來的View沒有 PrimaryKey(主索引鍵)

在Entity中,所有實體型別都必須要有個主鍵  ( 如果用LINQ To SQL 就不需要,因為原理不太一樣 )

一般在拉 Table 到 edmx 中的時候,沒有主鍵是沒辦法拉進來的,會出現下面的訊息並排除

image

但如果是View的話,Entity會自動幫你判斷主索引鍵

image

 

 

但如果他判斷出來的不是唯一的索引鍵,就會發生上面的窘境。

 

解決辦法就是在拉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

image

在搜尋一次,結果就會對了。