日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LINQ那些事儿(2)- 简单对象的CRUD操作和Association的级联操作

發(fā)布時(shí)間:2025/4/5 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LINQ那些事儿(2)- 简单对象的CRUD操作和Association的级联操作 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從(1)我們看到,當(dāng)生成entity class定義時(shí),entity class或xml mapping文件中都已經(jīng)完整的包含了entity和關(guān)系數(shù)據(jù)庫的映射信息了,LINQ2SQL會(huì)根據(jù)這些信息來把CRUD操作轉(zhuǎn)化為SQL提交給數(shù)據(jù)庫,并且把數(shù)據(jù)庫的返回DataTable封裝成我們想要的對(duì)象。

所謂簡(jiǎn)單對(duì)象,就是數(shù)據(jù)表定義中沒有Foreign-key的entity class,在操作這類對(duì)象時(shí)不會(huì)涉及級(jí)聯(lián)的操作。

簡(jiǎn)單對(duì)象的CRUD操作,可參考MSDN:http://msdn.microsoft.com/zh-cn/library/bb399349.aspx

有一點(diǎn)很方便,在插入數(shù)據(jù)時(shí),LINQ2SQL不但生成了Insert的SQL語句,而且還生成語句把ColumnAttribute標(biāo)記IsDbGenerated=true的數(shù)據(jù)列取回。這點(diǎn)當(dāng)我們用數(shù)據(jù)庫生成的uniqueidentifier列或自增id做主鍵時(shí)尤其方便。

下面讓我們來一起討論級(jí)聯(lián)操作以及相關(guān)問題,為了方便示例我定義了兩張數(shù)據(jù)表Publishers和Books:

其中PublisherID和BookID都是RowGuid,而且默認(rèn)值為newid(),以下代碼都是基于SqlMetal生成的xml mapping和entity class。

添加

下面代碼示例了在添加Publisher記錄時(shí),同時(shí)添加兩個(gè)關(guān)聯(lián)Book記錄

var context = GenerateContext(); Publisher publisher = new Publisher { Name = "Microsoft" }; publisher.Books.Add(new Book { Title = "Expert F#" }); publisher.Books.Add(new Book { Title = "Beautiful code" });context.Publishers.InsertOnSubmit(publisher); context.SubmitChanges();

提交成功,關(guān)聯(lián)對(duì)象的添加就好像是集合操作。但是,好像缺了點(diǎn)什么?我們好像沒有給Book.PublisherID賦值,作為外鍵沒有賦值為什么會(huì)沒拋出異常呢?這都是生成代碼的功勞,我們看看Publisher.Books屬性的定義

private EntitySet<Book> _Books;public Publisher() {this._Books = new EntitySet<Book>(new Action<Book>(this.attach_Books), new Action<Book>(this.detach_Books));OnCreated(); }

當(dāng)向Books集合中添加元素時(shí),會(huì)調(diào)用attach_Books讓Book.Publisher指向Publisher對(duì)象

private void attach_Books(Book entity) {this.SendPropertyChanging();entity.Publisher = this; }

而Book.Publisher的賦值又觸發(fā)事件使Book.PublisherId=Book.Publisher.PublisherID

public Publisher Publisher{get { … }set{Publisher previousValue = this._Publisher.Entity;if (((previousValue != value) || (this._Publisher.HasLoadedOrAssignedValue == false))){this.SendPropertyChanging();if ((previousValue != null)){this._Publisher.Entity = null;previousValue.Books.Remove(this);}this._Publisher.Entity = value;if ((value != null)){value.Books.Add(this);this._PublisherID = value.PublisherID;}else{this._PublisherID = default(System.Guid);}this.SendPropertyChanged("Publisher");}}}

更新

下面代碼示例了在更新Publisher記錄時(shí),同時(shí)更新相關(guān)的Book記錄

Publisher publisher = context.Publishers.Where( p => p.PublisherID == new Guid("ae825c5f-465d-4eb5-a2bb-cc1aeb5edb7d")).Single(); publisher.Name = "Updated Publisher"; var book = publisher.Books.First(); book.Title = "Updated book";context.SubmitChanges();

這樣的操作我們稱之為什么?級(jí)聯(lián)更新?事實(shí)上LINQ2SQL的實(shí)現(xiàn)里不存在所謂的“級(jí)聯(lián)更新“。在生命周期內(nèi),每一個(gè)DataContext對(duì)象都維護(hù)著每一個(gè)查詢獲得的對(duì)象的引用,并且跟蹤對(duì)象的修改,所有發(fā)生了修改的對(duì)象,在調(diào)用DataContext.SubmitChanges的時(shí)候,都會(huì)被保存到數(shù)據(jù)庫,這方面的內(nèi)容在”LINQ那些事(6)“里會(huì)詳細(xì)討論。所以,在這里不是級(jí)聯(lián)更新,而是Publisher和Book對(duì)象都發(fā)生了更改,所以在調(diào)用SubmitChanges都被保存了。

涉及Association的更新,有時(shí)還會(huì)引發(fā)異常,我們來看下面這段代碼:

var context = GenerateContext(); Publisher publisher = context.Publishers.Where( p => p.PublisherID == new Guid("ae825c5f-465d-4eb5-a2bb-cc1aeb5edb7d")).Single(); var book = publisher.Books.First(); publisher.Books.Remove(book);context.SubmitChanges();

這段代碼的意圖是刪除Publisher對(duì)象相關(guān)的某Book對(duì)象,看起來是很漂亮的集合操作,但是運(yùn)行時(shí)拋出異常:

“An attempt was made to remove a relationship between a Publisher and a Book. However, one of the relationship's foreign keys (Book.PublisherID) cannot be set to null.“

還記得我們?cè)谡{(diào)用Publisher.Books.Add時(shí)候,EntitySet的會(huì)調(diào)用attach_Books來修改Book.PublisherID嗎?在調(diào)用Publisher.Books.Remove的時(shí)候,EntitySet會(huì)調(diào)用detach_Books來讓Book.PublisherID = default(Guid)

而對(duì)于LINQ2SQL,只跟蹤到了Book.PublisherID屬性發(fā)生了更改,所以在調(diào)用SubmitChanges會(huì)嘗試更新Book記錄而產(chǎn)生上述外鍵異常。解決這個(gè)問題的方法是:在Book.PublisherID的ColumnAttribute定義中,把DeleteOnNull設(shè)為true。這樣當(dāng)Context發(fā)現(xiàn)Book.PublisherID為空(default(Guid)相當(dāng)于Guid.Empty)時(shí),不是執(zhí)行Update而是Delete操作。

刪除

根據(jù)msdn,目前版本的LINQ是不支持級(jí)聯(lián)刪除的,需要級(jí)聯(lián)刪除只能依賴數(shù)據(jù)庫的級(jí)聯(lián)刪除,否則也可以考慮下面的方式:

context.Books.DeleteAllOnSubmit(publisher.Books.AsEnumerable()); context.Publishers.DeleteOnSubmit(publisher); context.SubmitChanges();

你不需要擔(dān)心事務(wù)的問題,context.SubmitChanges在執(zhí)行時(shí)會(huì)自動(dòng)創(chuàng)建本地?cái)?shù)據(jù)庫事務(wù),來保證操作的完整。關(guān)于事務(wù)的問題,我們?cè)凇癓INQ那些事(3)”中會(huì)有詳細(xì)討論。

查詢

先看看下面這段代碼

var context = GenerateContext(); context.Log = Console.Out;// 查詢publisher對(duì)象 Console.WriteLine("Querying publisher"); Publisher publisher = context.Publishers.Where( p => p.PublisherID == new Guid("ae825c5f-465d-4eb5-a2bb-cc1aeb5edb7d")).Single();Console.WriteLine("Querying books") // 當(dāng)調(diào)用publisher.Books.GetEnumerator()時(shí),執(zhí)行book對(duì)象的查詢 foreach (Book book in publisher.Books) { Console.WriteLine(book.Title); }

在默認(rèn)情況下,DataContext并不會(huì)加載Assocation對(duì)象(EntitySet<T>或EntityRef<T>),當(dāng)Assocation對(duì)象需要被訪問時(shí)才會(huì)執(zhí)行數(shù)據(jù)庫查詢,這就是所謂的lazy-loading。LINQ2SQL的Layz-loading的實(shí)現(xiàn)與IEnumerable<T>的deferred query execution是一樣的,有興趣可以看看EntitySet<T>.GetEnumerator或EntityRef<T>.Entity.Getter代碼。

Lazy-loading的好處是避免了不必要的查詢,但是在某些場(chǎng)合確定Assocation對(duì)象都應(yīng)該加載時(shí),我們可以設(shè)置DataContext. LoadOption來指定Assocation對(duì)象的加載:

DataLoadOptions option = new DataLoadOptions(); option.LoadWith<Publisher>(p => p.Books); context.LoadOptions = option;

總結(jié):本節(jié)討論了如何使用LINQ2SQL來進(jìn)行簡(jiǎn)單對(duì)象和涉及Association的對(duì)象的CRUD操作。示例代碼段在只涉及一個(gè)DataContext對(duì)象或在單線程的情況下都可以正確運(yùn)行,但是當(dāng)涉及多個(gè)DataContext或并發(fā)訪問的情況的下會(huì)怎么樣呢?這是我們接下來要討論的。

?

鏈接

LINQ那些事(總)

1、 LINQ那些事兒(1)- 定義從關(guān)系數(shù)據(jù)庫到Entity Class的映射

2、 LINQ那些事兒(2)- 簡(jiǎn)單對(duì)象的CRUD操作和Association的級(jí)聯(lián)操作

3、 LINQ那些事兒(3)- 事務(wù)和并發(fā)沖突處理

4、 LINQ那些事兒(4)- Query Expression和Query Operator

5、 LINQ那些事兒(5)- 動(dòng)態(tài)查詢

6、 LINQ那些事兒(6)- DataContext的對(duì)象生命周期管理

7、 LINQ那些事兒(7)- 通過自定義IEnumerable<T>來擴(kuò)展LINQ

8、LINQ那些事兒(8)- 通過自定義IQueryable<T>和IQueryableProvider來擴(kuò)展LINQ

轉(zhuǎn)載于:https://www.cnblogs.com/chwkai/archive/2009/12/31/linq_crud.html

總結(jié)

以上是生活随笔為你收集整理的LINQ那些事儿(2)- 简单对象的CRUD操作和Association的级联操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: www欧美 | 91中文| 98视频在线| 乱人伦中文字幕 | 性生交大片免费看3p | 欧洲成人在线视频 | 91亚洲国产成人精品一区二区三 | 成人福利社 | 欧美日韩亚洲另类 | 蜜桃精品一区二区 | 亚洲乱码国产一区三区 | 女同在线观看 | 少妇一级淫免费放 | 亚洲国产成人精品激情在线 | 91传媒在线免费观看 | 超碰超碰超碰超碰 | 交专区videossex非洲 | 麻豆网站在线播放 | 色妞www精品视频 | 欧美日韩一区二区三区四区五区六区 | 国产女人18毛片水真多1 | 狠狠操中文字幕 | 梦梦电影免费高清在线观看 | 夜夜嗨av一区二区 | 穿情趣内衣被c到高潮视频 欧美性猛交xxxx黑人猛交 | 黄色生活毛片 | 乱老熟女一区二区三区 | 醉酒壮男gay强迫野外xx | 毛片a片免费观看 | 亚洲美女福利 | 艳妇av| 摸大乳喷奶水www视频 | 污污的视频在线观看 | 713电影免费播放国语 | 亚洲视频中文字幕在线观看 | 亚洲国产精品久久久久婷蜜芽 | 男生和女生靠逼视频 | 国产精品永久 | 美女免费福利视频 | 久久99久| av射进来 | 红桃视频隐藏入口 | 国产三级观看 | 丁香激情五月少妇 | 亚洲综合第一页 | 午夜精品久久久久久久蜜桃 | 好吊妞视频在线观看 | 欧美r级在线| 国产专区一区二区三区 | 成人性毛片 | 91中文字幕在线 | 黄色av网址在线观看 | 青青视频免费观看 | 午夜精品久久久久 | 久久精品2019中文字幕 | 99热在线这里只有精品 | 免费美女av | 国产精品不卡一区二区三区 | 自拍在线视频 | 日韩大片免费看 | 金鱼妻日剧免费观看完整版全集 | www噜噜噜 | 在线观看黄色小视频 | 亚洲一区二区三区在线播放 | 蘑菇视频黄色 | 精品国产一区二区在线观看 | 欧美老熟妇乱大交xxxxx | 一本色道久久综合亚洲精品小说 | 国产精品videossex久久发布 | 麻豆网站免费观看 | 瑟瑟视频在线看 | 秋霞欧美一区二区三区视频免费 | 欧美成人黑人猛交 | 蜜桃av在线播放 | 中国字幕av | 五月婷婷一区 | 美女脱了裤子让男人桶 | 欧美三级免费看 | 亚洲国产精选 | 色又黄又爽 | 国产大片一区 | 音影先锋av资源 | 自拍啪啪 | 美国色视频 | 欧美另类videosbestsex日本 | 欧美14sex性hd摘花 | 色干网 | 亚洲精品福利视频 | 在线成人免费电影 | 日韩成人在线观看 | 少妇又色又紧又爽又刺激视频 | 久久夜色网 | 精品97人妻无码中文永久在线 | 亚洲黄色一区二区三区 | 69久久久 | sm久久捆绑调教精品一区 | 色人阁在线视频 | 国产老女人精品毛片久久 | 国产精品无码专区 |