markdown
我有個功能,主要參照的TABLE因為一些問題而沒有設定PK,但是又想用MVC EF來開發,
於是我照著MVC課程的做法,建了一個VIEW,裡面包了一個虛擬的PK值,
Oracle View做法:
```
select ROWNUM as ID,table1.*
from table1
```
結果跳ERROR2003錯誤,EF無法辨認哪個是PK,
我在虛擬ID的欄位使用了nvl(null,1) as ID、nvl(ROWNUM,1) as ID, ROWNUM as ID、
都還是一樣跳ERROR 2003,
後來有人建議我手動去編輯EDMX的XML,就編修了半天,終於成功帶出資料了
基本上就是複製其他的格式來用
EDMX有三大區塊
1.SSDL content 資料庫的TABLE
2.CSDL content 模型的TABLE
3.C-S mapping content 對照用的區塊
原本正常加入的模型,系統會自動產生這三大區塊的XML碼,
但是現在這個出錯的模型在xml只有加入SSDL區,而且還被註解
```
<!--錯誤 6013: 資料表/檢視 '' 未定義主索引鍵,也無法推斷有效的主索引鍵。此資料表/檢視已被排除。如果要使用此實體,您必須檢閱您的結構描述,加入正確的索引鍵,並將它取消註解。
<EntityType Name="my_view">
<Property Name="ID" Type="number" Precision="38" Scale="0" Nullable="false" />
<Property Name="ORDER_NUMBER" Type="nvarchar2" MaxLength="11" />
<Property Name="CORRECT_ORDER" Type="number" Precision="38" Scale="0" />
<Property Name="SEND_DATE" Type="nvarchar2" MaxLength="8" />
<Property Name="EM_ID" Type="nvarchar2" MaxLength="4" />
<Property Name="CM_ID" Type="nvarchar2" MaxLength="8" />
<Property Name="COST" Type="number" Precision="38" Scale="0" />
</EntityType>-->
```
現在把註解移除,加上KEY值
```
<EntityType Name="my_view">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="number" Precision="38" Scale="0" Nullable="false" />
<Property Name="ORDER_NUMBER" Type="nvarchar2" MaxLength="11" />
<Property Name="CORRECT_ORDER" Type="number" Precision="38" Scale="0" />
<Property Name="SEND_DATE" Type="nvarchar2" MaxLength="8" />
<Property Name="EM_ID" Type="nvarchar2" MaxLength="4" />
<Property Name="CM_ID" Type="nvarchar2" MaxLength="8" />
<Property Name="COST" Type="number" Precision="38" Scale="0" />
</EntityType>
```
EntityType 加上去後,要去SSDL區最後一塊EntityContainer裡面加上一行
```
<EntityContainer Name="ModelStoreContainer">
<EntitySet Name="table1" EntityType="Self.table1" Schema="myDB" store:Type="Tables" />
<EntitySet Name="table2" EntityType="Self.table2" Schema="myDB" store:Type="Tables" />
<EntitySet Name="table3" EntityType="Self.table3" Schema="myDB" store:Type="Tables" />
<!--這行-->
<EntitySet Name="my_view" EntityType="Self.my_view" Schema="myDB" store:Type="Tables" />
</EntityContainer>
```
再來是CSDL的部分,這區系統就完全沒有產生XML了,同樣要填入EntityType 與EntityContainer,
但要注意的是這區的欄位Type是C#的型態,
例如number就是Decimal,nvarchar2就是String,
如果是String欄位,好像還要加上 FixedLength="true/false" Unicode="true/false"屬性
把前面SSDL的架構複製貼上到這區,並且修改TYPE為C#型態
```
<EntityType Name="my_view">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="Decimal" Precision="38" Scale="0" Nullable="false" />
<Property Name="ORDER_NUMBER" Type="String" MaxLength="11" FixedLength="false" Unicode="true" />
<Property Name="CORRECT_ORDER" Type="Decimal" Precision="38" Scale="0" />
<Property Name="SEND_DATE" Type="String" MaxLength="8" FixedLength="false" Unicode="true"/>
<Property Name="EM_ID" Type="String" MaxLength="4" FixedLength="false" Unicode="true" />
<Property Name="CM_ID" Type="String" MaxLength="8" FixedLength="false" Unicode="true"/>
<Property Name="COST" Type="Decimal" Precision="38" Scale="0" />
</EntityType>
```
再來同樣在EntityContainer加上一行
```
<EntityContainer Name="myDBEntities" annotation:LazyLoadingEnabled="true">
<EntitySet Name="table1" EntityType="Self.AS400_ZDF201" />
<EntitySet Name="table2" EntityType="Self.AS400_ZDF203" />
<EntitySet Name="table3" EntityType="Self.AS400_ZDF25A" />
<!--這行-->
<EntitySet Name="my_view" EntityType="Self.my_view" />
</EntityContainer>
```
最後是CS-SS對應區,加上這個view的EntitySetMapping
```
<EntitySetMapping Name="my_view">
<EntityTypeMapping TypeName="Model.my_view">
<MappingFragment StoreEntitySet="my_view">
<ScalarProperty Name="ID" ColumnName="ID" />
<ScalarProperty Name="ORDER_NUMBER" ColumnName="ORDER_NUMBER" />
<ScalarProperty Name="CORRECT_ORDER" ColumnName="CORRECT_ORDER" />
<ScalarProperty Name="SEND_DATE" ColumnName="SEND_DATE" />
<ScalarProperty Name="EM_ID" ColumnName="EM_ID" />
<ScalarProperty Name="CM_ID" ColumnName="CM_ID" />
<ScalarProperty Name="COST" ColumnName="COST" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
```
然後F6編譯,雖然還是會出現ERROR2003,但是建立Controller之後我已經可以撈出資料了!
不過不知道這樣手動增加,之後還會跑出什麼問題...
2015年7月23日 星期四
2015年3月31日 星期二
SPA專案架構
MVC書一次都教一堆東西...
RAZOR語法、實體資料庫模型、LINQ語法、IENUMERABLE型態...
實在有點懶的學
20150403補充:原來這個叫做SPA架構
前輩教的類MVC架構
1.Modal-就只是個Modal,放屬性欄位而已
2.DAL-資料庫存取相關功能(Data Access Level)
3.主要專案-前端功能
應用在網站專案、Console專案、winform等等都可
1.Visuao Studio建立空白解決方案
2.建立類別庫專案-Modal,想到再加入類別即可
3.建立類別庫專案-DAL
4.建立主要專案,以一般ASP.NET網站專案為例
網站專案加入參考Modal與DAL
DAL加入Modal參考
Modal不參考任何專案,獨立
5.假設要做一個客戶主檔維護功能,有新增刪除修改顯示(CRUD)基本功能
客戶主檔資料表:
SID、客戶名稱、客戶電話三個欄位就好
Modal底下建立客戶主檔類別
public class Customer
{
///<summary>流水號</summary>
public int SID{get;set;}
///<summary>客戶名稱</summary>
public string Name {get;set;}
///<summary>客戶電話</summary>
public string PhoneNumber {get;set;}
}
新增、更新、刪除時的訊息類別
public class msgCRUD
{
public static const string STATUS_SUCCESS="success";
public static const string STATUS_ERROR="error";
public string status {get;set;}
public string msg {get;set;}
}
DAL底下建立類別
using Modal;
public class CustomerController
{
public List<Customer> searchData(out msgCRUD msg)
{
msg=new msgCRUD();
List<Customer> list=new List<Customer>();
DataTable dt=new DataTable();
try
{
//資料庫處理,結果塞到DataTable
if(dt.Rows.Count>0)
{
foreach(DataRow dr in dt.Rows)
{
list.Add(new Customer(){
SID = dr["SID"].ToString(),
Name = dr["Name"].ToString(),
PhoneNumber = dr["PhoneNumber"].ToString()
});
}
}
}
catch(Exception ex)
{
msg.status=msgCRUD.STATUS_ERROR;
msg.msg="搜尋時發生錯誤:"+ex.ToString();
}
return list;
}
}
網站專案底下建立ASP網頁
後端Customer.aspx.cs
[WebMethod]
protected string searchData()
{
CustomerController cc=new CustomerController();
List<Customer> list=cc.searchData();
string myJson=JsonConvert.SerializeObject(list);
return myJson;
}
前端Customer.aspx
使用JQuery AJAX語法取得資料
...
</form>
<script type="javascript">
function searchData()
{
if (!window.ajaxValidPass) {
var sdata = { };
$.ajax({
type: "POST",
async: true,
url: "Customer.aspx/searchData",
data: JSON.stringify(sdata),
contentType: "application/json; charset=UTF-8",
dataType: 'json',
success: function (data) {
var ary = $.parseJSON(data.d);
if (ary) {
//處理撈回來的東西
}
else {
alert('找不到資料');
}
}
},
error: function (response) {
console.log('error:' + response.responseText);
alert('error:' + response.responseText);
}
});
}
}
</script>
到此即為基本的前端到後端,後端到資料存取層的資料傳輸方式
可以擺脫Server Control夾帶的垃圾CODE
又可以保持架構上的彈性
RAZOR語法、實體資料庫模型、LINQ語法、IENUMERABLE型態...
實在有點懶的學
20150403補充:原來這個叫做SPA架構
前輩教的
1.Modal-就只是個Modal,放屬性欄位而已
2.DAL-資料庫存取相關功能(Data Access Level)
3.主要專案-前端功能
應用在網站專案、Console專案、winform等等都可
1.Visuao Studio建立空白解決方案
2.建立類別庫專案-Modal,想到再加入類別即可
3.建立類別庫專案-DAL
4.建立主要專案,以一般ASP.NET網站專案為例
網站專案加入參考Modal與DAL
DAL加入Modal參考
Modal不參考任何專案,獨立
5.假設要做一個客戶主檔維護功能,有新增刪除修改顯示(CRUD)基本功能
客戶主檔資料表:
SID、客戶名稱、客戶電話三個欄位就好
Modal底下建立客戶主檔類別
public class Customer
{
///<summary>流水號</summary>
public int SID{get;set;}
///<summary>客戶名稱</summary>
public string Name {get;set;}
///<summary>客戶電話</summary>
public string PhoneNumber {get;set;}
}
新增、更新、刪除時的訊息類別
public class msgCRUD
{
public static const string STATUS_SUCCESS="success";
public static const string STATUS_ERROR="error";
public string status {get;set;}
public string msg {get;set;}
}
DAL底下建立類別
using Modal;
public class CustomerController
{
public List<Customer> searchData(out msgCRUD msg)
{
msg=new msgCRUD();
List<Customer> list=new List<Customer>();
DataTable dt=new DataTable();
try
{
//資料庫處理,結果塞到DataTable
if(dt.Rows.Count>0)
{
foreach(DataRow dr in dt.Rows)
{
list.Add(new Customer(){
SID = dr["SID"].ToString(),
Name = dr["Name"].ToString(),
PhoneNumber = dr["PhoneNumber"].ToString()
});
}
}
}
catch(Exception ex)
{
msg.status=msgCRUD.STATUS_ERROR;
msg.msg="搜尋時發生錯誤:"+ex.ToString();
}
return list;
}
}
網站專案底下建立ASP網頁
後端Customer.aspx.cs
[WebMethod]
protected string searchData()
{
CustomerController cc=new CustomerController();
List<Customer> list=cc.searchData();
string myJson=JsonConvert.SerializeObject(list);
return myJson;
}
前端Customer.aspx
使用JQuery AJAX語法取得資料
...
</form>
<script type="javascript">
function searchData()
{
if (!window.ajaxValidPass) {
var sdata = { };
$.ajax({
type: "POST",
async: true,
url: "Customer.aspx/searchData",
data: JSON.stringify(sdata),
contentType: "application/json; charset=UTF-8",
dataType: 'json',
success: function (data) {
var ary = $.parseJSON(data.d);
if (ary) {
//處理撈回來的東西
}
else {
alert('找不到資料');
}
}
},
error: function (response) {
console.log('error:' + response.responseText);
alert('error:' + response.responseText);
}
});
}
}
</script>
到此即為基本的前端到後端,後端到資料存取層的資料傳輸方式
可以擺脫Server Control夾帶的垃圾CODE
又可以保持架構上的彈性
訂閱:
文章 (Atom)