1. 程式人生 > >EF多表關聯資料更新

EF多表關聯資料更新

本篇是第一階段的完結篇。

學完這篇後,你應該可以利用MVC進行完整專案的開發了。

本篇主要講述多表關聯資料的更新,以及如何使用原生SQL。

文章提綱

  • 多表關聯資料更新
  • 如何使用原生SQL
  • 總結

多表關聯資料更新

我們在第四篇文章已經講過資料的更新了,不過那個是針對單表結構的更新。

這次我們講下使用EF進行關聯資料的更新。

關聯資料更新有兩種情況:

1.一對多

2.多對多

第一種情況關聯表有主外來鍵關聯,只要簡單的更新外來鍵值就可以了(相當於更新單表),我們主要講解第二種多對多的情況。

使用之前很熟悉的模型:

我們定義一個場景:    

一個使用者可以有任意多個角色,一個角色可以有任意多個使用者。

我們接下來完成下面操作:

編輯某個使用者時,顯示該使用者的角色進行編輯。

即 更新某個使用者(SysUser表)及其相關的角色(SysUserRole表)。

詳細步驟:

1.先新增一個ViewModel, 用來表示角色是否分配給某個使用者。

2.開啟UserRoleController,新增一個Edit的Action用來顯示編輯頁面。

有兩點說明一下:

a.我們沿用上一篇文章的模型,多了一個SysDepartment,實際模型如下:

b.PopulateAssigenedRoleData將特定使用者下選中的角色標記出來。

3.開啟Views\UserRole\Index.cshtml, 增加一個編輯按鈕

4.再根據Edit Action自動生成Edit View

修改相關內容,主要是兩點:

a.部門

b.角色

角色是通過一組checkbox來顯示的。

Checkbox顯示資料庫中所有角色,已分配給使用者的會顯示選中狀態。

通過勾選checkbox的方式來實現使用者角色的更新。

說明

角色少這樣弄沒問題,如果多的話經典的做法,可以用兩個listbox,中間用箭頭將左右兩邊的選項移動。本篇文章主要說明關聯表的更新,後續文章我們會提供更好的做法的示例。

執行下Index頁面。

進入編輯頁面。

這樣編輯的顯示功能就已經完成了。

可以看到,用一組checkbox表示roles是否選中。

5.最後再完成HttpPost的Edit功能。

首先更新SysUser表:

用model binder中的值更新entity: userToUpdate.

可以看到,我們使用了白名單指定資料庫中需要更新的欄位。

TryUpdateModel(userToUpdate,"",

new string[] {"LoginName","Email","Password","CreateDate","SysDepartmentID"})

再更新SysUserRole表:

將資料庫中值和編輯後的值進行比對,基本邏輯是:

如果被選中了,原來沒有的要新增;

如果沒被選中,原來有的要刪除。

UpdateUserRoles(selectedRoles, userToUpdate);

注意在UpdateUserRoles裡,我新建了一個連線

using (AccountContext db2=new AccountContext())

如果用之前的db會報如下錯誤:

已有開啟的與此 Command 相關聯的 DataReader,必須首先將它關閉。

重新執行下Index, 如下一組圖,這時我們看到角色編輯已經起作用了。

至此,多表更新的示例就介紹到這,其他情況相信你可以舉一反三自己推匯出來做法。

使用原生SQL

使用EF的一個優點就是自動幫我們生成SQL,這在常規情況下很方便,但有些情況下用EF卻不適合。

例如我們上面更新SysUserRole這張表時,每次增減一條資料,要迴圈很多次。

另外還有些特別複雜的語句,利用EF很難生成。

EF提供一組方法用來執行原生的SQL.

有以下三種:

1.DbSet.SqlQuery

2.Database.SqlQuery

3.Database.ExecuteSqlCommand

這三種有啥區別呢?我們來看例子。

對三種形式我們各舉一例。

例子1:DbSet.SqlQuery查詢並返回Entities

我們開啟Controllers\AccountController.cs做實驗

找到Details方法

將註釋的部分改成方框部分即可。

方框中的和註釋掉的內容SysUser sysUser=db.SysUsers.Find(id)完全一樣。

前端顯示效果不變:

注意兩點:

1.構造帶引數的SQL語句(養成好習慣,防止SQL注入,總是用帶引數的SQL語句)

2.此處使用的是DbSet<TEntity>執行SQL方法,返回的直接是Entity, 和LINQ查詢一樣。如果暫時不熟悉LINQ,用這種方法替換(作為一個過渡),可以讓你快速的使用起新框架。

這種情況有一些缺陷,例如

SELECT LoginName as UserName,* FROM [dbo].[SysUser] WHERE [email protected]

大家可以看到我添加了LoginName as UserName,這是因為Model中用了Column Attribute,資料庫中存的欄位是LoginName

這樣我如果不轉換,model就會找不到匹配的欄位而出錯,而如果用db.SysUsers.Find(id) 就可以智慧轉換。

例子2 Database.SqlQuery 返回其他型別

string query = "select loginName from SysUser";

var names=db.Database.SqlQuery<string>( query).ToList();

以上會返回一個System.Collections.Generic.List<string>型別。

這種方式和第一種情況最大的區別就是返回non-entity 型別。

我們可以根據需要,自己構建需要的型別。

我們也可以自定義一個entity type讓它返回,例如類似我們上一個例子:

SysUser sysUser = db. Database.SqlQuery(query, paras).SingleOrDefault();

這樣也可以返回entity, 但要注意,這種方式將不會被context track, 返回後就沒關係了,如果我們在View中用類似於Model.XXX導航屬性獲取其他關聯資料就會報錯。例如@foreach (var item in Model.SysUserRoles),這種情況下會報Model為null的錯誤。

例子3:Database.ExecuteSqlCommand執行更新語句

最後一個是更新的,直接看示例就明白了:

context.Database.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));

最後提下執行儲存過程,也類似,我就不多說了,如下MSDN(https://msdn.microsoft.com/en-us/data/jj592907)截圖。

原生SQL使用總結

原生SQL執行查詢:

需要返回實體模型,使用DbSet.SqlQuery (context會跟蹤,等效於LINQ方式)

需要返回其他型別,使用Database.SqlQuery

原生SQL執行更新:

使用Database.ExecuteSqlCommand

至此,本系列文章的第一階段(1~10)就結束了,下一階段再見。

感謝支援,祝學習進步!

P.S. 方便大家觀看,列出系列文章地址:

相關推薦

EF關聯資料更新

本篇是第一階段的完結篇。 學完這篇後,你應該可以利用MVC進行完整專案的開發了。 本篇主要講述多表關聯資料的更新,以及如何使用原生SQL。 文章提綱 多表關聯資料更新 如何使用原生SQL 總結 多表關聯資料更新 我們在第四篇文章已經講過資料的更新了,不過那

Oracle關聯如何更新個字段

表關聯 select 結果集 sele 部分 date sts 條件 from 註意點:1、被update主表一定要加上過濾條件。2、查詢出來更新結果集,同時也要作為被更新主表的條件,作為同步大家都是更新這部分數據。update student stu  set (stu.

提高關聯資料查詢效率

前期做了一個專案,使用sqlservice資料庫,後來發現數據量越多,對應的系統反應速度就越慢,7萬多條資料反應要5~6秒,後來試了一下,看看檢視是否能提高點效率,雖然網上說是沒用的,可是自己還是試了一下,結果的確沒有效果。於是乎,本人就想,檢視能否建個索引試一下呢,於是,

MVC+EF關聯數據更新

選項 數據 返回 tro view ont 方式 自動 連接 多表關聯數據更新關聯數據有兩種:一種是一對多,一種總是多對多eg:假設一個用戶可以有任意多個角色,一個角色可以有任意多個用戶。 下面來實現編輯某個用戶時,顯示該用戶的角色進行編輯。步驟:1.先添加一個ViewMo

ef 添加(關聯

[] tin product cnblogs 增加 pro save 關聯 添加 static void Main(string[] args){      //創建上下文對象 PpDbEntities dbEntities = new PpDbE

關聯更新sql

cheng upan update 表關聯 關聯 sel mce date 多表 UPDATE S_fangyuanxinxi SET wuyeleixing = (SELECT s_dalou.yongtu FROM s_dalou

MySQL5.7關聯更新

mysqlupdate ord ainner join room b on a.roomno=b.roomnoinner join flat c on a.flatno = c.flatno and a.flatsub=c.flatsubset a.xrea = b.xrea,a.ritysubn=b.rit

Oracle 關聯更新

upd from ber char set var rom rac reat create table t1(   id number(10),   name varchar2(10));create table t2(   id num

關聯更新

有A、B張表,其記錄如下: A表 c1       c2 -------------- 1       a1 2       a2 3       a3 8       a8 B表 c1       c3 -------------- 1        b1

mybatis 關聯查詢時,如果使用resultType作為輸出對映時,估計會出現重複資料

mybatis 多表關聯查詢時,一般建議還是使用把需要關聯的表的pojo新增到主表對應的pojo中作為它的屬性,這樣在mapper.xml檔案中可以使用assacition(一對一查詢),或者colletion(一對多查詢)來使用resultMap作為輸出對映。 不過最近我

MySQL 關聯更新及刪除

一、      多表關聯更新 問題描述:現有tdb_goods表(含有具體資訊)和tdb_goods_cates表(沒有具體資訊),需要查詢tdb_goods表的所有記錄,並且按"類別"分組,且將分組結果寫入到tdb_goods_cates資料表。然後通過tdb_goods

MySQL百萬級、千萬級資料關聯SQL語句調優

本文不涉及複雜的底層資料結構,通過explain解釋SQL,並根據可能出現的情況,來做具體的優化,使百萬級、千萬級資料表關聯查詢第一頁結果能在2秒內完成(真實業務告警系統優化結果)。希望讀者能夠理解SQL的執行過程,並根據過程優化,走上自己的"成金之路" 需要優化的查

UPDATE關聯更新時為什麼會慢

構建環境如下: Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 Connected as [email protected]:1521/orcl SQL> C

oracle的關聯更新或者插入

http://blog.csdn.net/yuzhic/article/details/1896878 http://blog.csdn.net/macle2010/article/details/5980965 該命令使用一條語句從一個或者多個數據源中完成對錶的更新和插入資料. OR

mysql關聯查詢進行資料修改

 問題描述:進行update某個表資料的時候,需要關聯查詢若干表進行篩選過濾.  問題解決:  UPDATE t_order_third AS t  INNER JOIN t_order_attach

mysql 關聯一對查詢最新的一條資料 深坑等你

注意核心要點: yii2 多表關聯查詢單欄位去重沒有生效 原因是 單表的唯一查詢用:distinct 多表的唯一查詢用:group by –但是注意下面的坑 參考: https://blog.csdn.net/lkforce/article/det

update left join 關聯更新

UPDATE table_1 t1 left join table_2 t2 on t2.id = t1.tid SET t1.username = t2.uname where t1.id>5

JPA條件組合查詢,關聯查詢,資料條數(CriteriaQuery)

JPA多條件組合查詢(CriteriaQuery) /**查詢Demo結果集 * @return */ public List<Demo> findDemoList(ParamVO param,Pageable pageabl

SQL update關聯更新

UPDATE 表2 SET 表2.C = (SELECT B FROM 表1 WHERE 表1.A = 表2.A) WHERE exists ( SELECT 1 FROM 表1 WHERE 表1.A = 表2.A) ; update TA a set(name, re

Oracle關聯更新(update關聯

.Oracle沒有update from語法,可以通過兩種實現方式: 1、利用子查詢:      update    A        SET    欄位1=(select    欄位表示式    from    B    WHERE    ...),