ScottGu之博客翻译-LINQ to SQL第四部分,更新数据库 LINQ to SQL (Part 4 - Updating our Database)...
原貼鏈接:
http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx
?
Over the last few weeks I've been writing a series of blog posts that cover LINQ to SQL.? LINQ to SQL is a built-in O/RM (object relational mapper) that ships in the .NET Framework 3.5 release, and which enables you to easily model relational databases using .NET classes.? You can use LINQ expressions to query the database with them, as well as update/insert/delete data.
上個月我開始了一個講解LINQ to SQL的帖子系列。LINQ to SQL是集成在.NET Framework3.5中的O/RM(對象關系映射)的實現,它讓你非常容易地用.NET類來生成關系型數據庫的模型。然后你可以用LINQ 表達式對它來進行查詢,更新,插入刪除。
Below are the first three parts of my LINQ to SQL series:
下邊是我的前三篇的帖子的鏈接:
- Part 1: Introduction to LINQ to SQL
- Part 2: Defining our Data Model Classes
- Part 3: Querying our Database
In today's blog post I'll cover how we we can use the data model we created earlier, and use it to update, insert, and delete data.? I'll also show how we can cleanly integrate business rules and custom validation logic with our data model.
在今天的帖子中,我將會講解一下如何使用我們在前幾篇帖子中生成數據模型,并且用它來更新、插入、刪除數據。我還會展示一下如何將我們的業務規則和自定義的驗證與我們的數據模型進行集成。
Northwind Database Modeled using LINQ to SQL
用LINQ to SQL建成的Northwind數據庫模型
?
In Part 2 of this series I walked through how to create a LINQ to SQL class model using the LINQ to SQL designer that is built-into VS 2008.? Below is a class model?created for the Northwind sample database and which I'll be using in this blog post:
在本系列的第二部分(Part 2)中我講解了如何用內置在VS2008中的LINQ to SQL設計器來生成一個LINQ to SQL類模型。下邊是用LINQ to SQL設計器生成的一個Northwind事例的模型,在本篇博客中將會用到它。
?
?
When we designed our data model using the LINQ to SQL data designer above we defined five data model classes: Product, Category, Customer, Order and OrderDetail.? The properties of each class map to the columns of a corresponding?table in the database.? Each instance of a class entity represents a row within the database table.
在用LINQ to SQL數據設計器設計數據模型時,我們定義了一個數據模型類:Product,Category,Customer,Order和OrderDetail。類的屬性映射到數據庫相應的數據表的列上。每個類的實體代表了數據表的一條記錄。
?
When we defined our data model, the LINQ to SQL designer also created a custom DataContext class that provides the main conduit by which we'll query our database and apply updates/changes.? In the example data model we defined above this class was named "NorthwindDataContext".? The NorthwindDataContext class has properties that represent each Table we modeled within the database (specifically: Products, Categories, Customers,?Orders, OrderDetails).
當我們在定義數據模型時,LINQ to SQL設計器也自動生成了一個DataContext類,該類提供了我們查詢數據庫和提交更新及變更的一個主要通道。在我們上面定義的數據模型事例中,這個類的名字叫"NorthwindDataContext",NorthwindDataContext類含有代表了在數據庫中我們建立模型的表的屬性(具體來說就是:Product,Categories,Customers,Orders,OrderDetails)。
?
As I covered in Part 3 of this blog series, we can easily use LINQ syntax expressions to query and retrieve data from our database using this NorthwindDataContext class.? LINQ to SQL will then automatically translate these LINQ query expressions to the appropriate SQL code to execute at runtime.
在本系列的第3部分(Part 3)中我講過,我們可以用這個NorthwindDataContext類通過方便地寫LINQ語法表達式來對數據庫進行查詢和檢索數據庫。LINQ to SQL將會在運行時自動地將LINQ 表達式轉換為適當的SQL語句。
?
For example, I could write the below LINQ expression to retrieve a single Product object by searching on the Product name:
例如,我可以寫如下的LINQ 表達式來通過Product名稱對產品查詢出一個Product對象:
I could then write the LINQ query expression below to retrieve all products from the database that haven't yet had an order placed for them, and which also cost more than $100:
?
我可以寫如下的LINQ 查詢表達式來完成滿足以下條件的查詢:沒有訂單的,單價超過100美元的。
Note above how I am using the "OrderDetails" association for each product as part of the query to only retrieve those products that have not had any orders placed for them.
注意上面我是如何用每個產品的"OrderDetails"這個關聯來查詢的一部分,并通過它來查出那些尚未有訂單的產品記錄。
?
Change Tracking and DataContext.SubmitChanges()
變更跟蹤和DataContext.SubmitChanges()方法
?
When we perform queries and retrieve objects?like the product instances above, LINQ to SQL will by default keep track of any changes or updates?we later make to these objects.? We can make any number of queries and changes we want using a LINQ to SQL DataContext, and these changes will all be tracked together.?
當查詢并檢索出像上邊的Product實例的對象時,LINQ to SQL將會默認地保持著對該對象任何的我們對這些對象所做的變化或更新的跟蹤。通過LINQ to SQL的DataContext我們可以寫許許多多的查詢和更新,這些變化將會被保存在一起。
?
Note: LINQ to SQL change tracking happens on the consuming caller side - and not in the database.? This means that you are not consuming any database resources when using it, nor do you need to change/install anything in the database to enable it.
注意:LINQ to SQL的變化追蹤只在調用端被保存――而不是在數據庫端。這意味著在使用它時,你既不需要任何的數據庫資源,也不需要在數據庫中更改/安裝任何的東西。
After making the changes we want to the objects we've retrieved from LINQ to SQL, we can then optionally call the "SubmitChanges()" method on our DataContext to apply the changes back to the database.? This will cause LINQ to SQL to dynamically calculate and execute the appropriate SQL code to update the database.
?
在對我們從LINQ to SQL中查詢出來的對象進行了變化之后,我們可以選擇調用DataContext的SubmitChanges()方法來將更新返回給數據庫。這將會導致LINQ to SQL動態地生成并執行適當的SQL語句來更新數據庫。
For example, I could write the below code to update the price and?# of units in?stock?of the "Chai" product in the database:
?
例如,我可以寫如下的代碼來更新數據庫中的產品名稱為"Chai"的產品的價格和存儲數量:
When I call northwind.SubmitChanges() above, LINQ to SQL will dynamically construct and execute a SQL "UPDATE" statement that will update the two product property values we modified above.
在調用Northwindo.SubmitChanges()時,LINQ to SQL將會動態地構建LINQ to SQL語句并執行一個SQL語句中的"UPDATE"聲明,該聲明將會更新我們上面修改的兩個屬性。
?
I could then write the below code to loop over unpopular, expensive products and set the "ReorderLevel" property of them to zero:
?
然后我可以寫如下的代碼來通過遍歷不受歡迎的,貴的產品,將它們的"ReorderLevel"屬性設置為0:
When I call northwind.SubmitChanges() above, LINQ to SQL will calculate and execute an appropriate set of UPDATE statements to modify the products who had their ReorderLevel property changed.
當我調用northwind.SubmitChange()方法時,LINQ to SQL將會生成并執行的將ReorderLevel屬性變化的產品記錄的相應字段更新的語句。
?
Note that if a Product's property values weren't changed by the property assignments above, then the object would not be considered changed and LINQ to SQL would therefore not execute an update for that product back to the database.? For example - if the "Chai" product's unitprice was already $2 and the number of units in stock was 4, then calling SubmitChanges() would not cause any database update statements to execute.? Likewise, only those products in the second example whose ReorderLevel was not already 0 would be updated when the SubmitChanges() method was called.
?
注意,如果一個產品的屬性值沒有被上邊的屬性聲明給更改,那個這個對象將不會被認為被更改過了,LINQ to SQL也因此不會為那條產品到數據庫中執行一條Update語句。例如,如果"Chai"產品 的單價已經是2美元,并且庫存數量也是4,那么調用SubmitChanges()方法將不會執行任何的Update語句。同樣的,第2個事例中,只有那些ReorderLevel還不是0的產品才會在調用SubmitChange()方法時被更新。
?
Insert and?Delete Examples
插入和刪除事例
?
In addition to updating existing rows in the database, LINQ to SQL obviously also enables you to insert and delete data.? You can accomplish this by adding/removing data objects from the DataContext's table collections, and by then calling the SubmitChanges() method. ?LINQ to SQL will keep track of these additions/removals, and automatically execute the appropriate SQL INSERT or DELETE statements when SubmitChanges() is invoked.
?
除了允許你更新在數據庫已有的數據記錄之后,LINQ to SQL顯然也允許你向數據庫中插入和刪除數據庫。你可以通過在DataContext的表集合中添加/刪除對象,然后調用SubmitChanges()方法來完成對數據插入和刪除。LINQ to SQL將會跟蹤這些添加和刪除的動作,并且當SubmiChanges()被觸發時執行適當的Insert或Delete的SQL語句。
Inserting a New Product
插入一條新產品
I can add a new product to my database by creating a new "Product" class instance, setting its properties, and then by adding it to my DataContext's "Products" collection:
?
我可以通過如下方式來向數據庫中添加一條新的產品記錄:生成一個新的"Product"類的實例,設置其屬性,然后將它添加到DataContext的"Product"集合中:
When we call "SubmitChanges()" above a new row will be created in our products table.
然后調用上面的SubmitChanges()方法時,一條新記錄將會添加到Products數據表中。
?
Deleting Products
刪除產品記錄
?
Just as I can express that I want to add a new Product to the database by adding a Product object into the DataContext's?Products collection, I can likewise express that I want to delete a product from a database by removing it from the DataContext's Products collection:
就像上面我可以通過將一個Product對象添加到DataContext的Products集合中來實現添加一條記錄到數據庫中那樣,我同樣也可以通過從DataContext的產品集合中移除一個Product對象來完成對數據庫中記錄的刪除:
?
Note above how I'm retrieving a sequence of discontinued products that no one has ever ordered using a LINQ query, and then passing it to the RemoveAll() method on my DataContext's "Products" collection.? When we call "SubmitChanges()" above all of these Product rows will be deleted from our products table.
?注意上面我用LINQ查詢來檢索出一個不再出售的,訂單數量為0的產品結果集,然后將它傳到DataContext的Products集合的RemoveAll()方法中。當我們調用 SubmitChanges()訪求時,所有的這些記錄將會從數據庫中刪除。
?
Updates across Relationships
通過關系進行更新
?
What makes O/R mappers like LINQ to SQL extremely flexible is that they enable us to easily model cross-table relationships across our data model.? For example, I can model each Product to be in a Category, each Order to contain OrderDetails for line-items, associate each OrderDetail line-item with a Product, and have each Customer contain an associated set of Orders.? I covered how to construct and model these relationships in Part 2 of this blog series.
使得O/R映射器,比如LINQ to SQL,特別靈活的是它們允許我們非常方便地通過我們的數據模型來對交叉的表間關系進行建模。例如,我可以將每個Product放到一個Category中,每條Order可以包含OrderDetails,將每個OrderDetail的數據項跟產品關聯起來,每個有一套訂單。在本系列的第二部分(Part 2)我講解了如何組織并生成這些關系。
?
LINQ to SQL enables me to take advantage of these relationships for both querying and updating my data. For example, I could write the below code to create a new Product and associate it with an existing "Beverages" category in my database like so:
?
LINQ to SQL使得我在查詢和更新我的數據時均可以使用這些關系。例如,我可以寫如下的代碼來生成一條新產品記錄,并將它與在數據庫中已經存在的"Beverages"類別關聯起來:
Note above how I'm adding the Product object into the Category's Products collection.? This will indicate that there is a relationship between the two objects, and cause LINQ to SQL to automatically maintain the foreign-key/primary key relationship between the two when I call "SubmitChanges()".
注意上面我如何將一個Product對象添加到類別的Products集合中。這表明了在兩個對象之間存在著關系,并且使得在調用SubmitChanges()方法時LINQ to SQL自動地維護外鍵/主鍵關系。
?
For another example?of how LINQ to SQL can help manage cross-table?relationships for us?and help clean up our code, let's look at an example below where I'm creating a new Order for an existing customer.? After setting the required ship date and freight costs for the order, I then?create two order line-item objects that point to the products the customer is ordering.? I then associate the order with the customer, and update the database with all of the changes.
另外一個關于LINQ to SQL如何幫助我們管理表間交叉的關系并且使得我們的代碼更清潔的例子,讓我們看一下下面的一個為已經存在的客戶生成一條訂單的事例。在設置了請求的時間和訂單的運費之后,我生成了兩個指向客戶訂下的產品的Order對象。然后將這個訂單和客戶關聯起來,并且將所有的這些變更更新至數據庫。
?
As you can see, the programming model for performing all of this work is extremely clean and object oriented.?
正如你看到的,實現所有這些工作的編程模型特別的簡單,并且是面向對象的。
?
Transactions
?
事務
?
A transaction is a service provided by a database?(or other resource manager)?to guarantee that a series of individual actions occur atomically - meaning either they all succeed or they all don't, and if they don't then they are all automatically undone before anything else is allowed to happen.
?
事務是數據庫(或者其他的資源管理器)提供的一種服務,該服務能保證一系列單獨的行為自動的觸發――也就是要么它們全部成功,要么就不成功,如果不成功的話,它們將會在允許做其他事情之前自動地回滾。
?
When you call SubmitChanges() on your DataContext, the updates will always be wrapped in a Transaction.? This means that your database will never be in an inconsistent state if you perform multiple changes - either all of the changes you've made on your DataContext are saved, or none of them are.
?
當你調用DataContext的SubmictChanges()方法時,更新部分總是會被包裝在一個事務中。這意味著如果你執行了多步變更的話,你的數據庫永遠不會處于不一致的情況――要么將你所有對DataContext做的變化保存至數據庫,要么全不保存。
?
If no transaction is already in scope, the LINQ to SQL DataContext object will automatically start a database transaction to guard updates when you call SubmitChanges(). Alternatively, LINQ to SQL also enables you to explicitly define and use your own TransactionScope object (a feature introduced in .NET 2.0).? This makes it easier to integrate LINQ to SQL code with existing data access code you already have.? It also means that you can enlist non-database resources into the transaction - for example: you could send off a MSMQ message, update the file-system (using the new transactional file-system support), etc - and scope all of these work items in the same transaction that you use to update your database with LINQ to SQL.
?
如果沒有已經排除的事務,LINQ to SQL DataContext將會在調用SubmitChanges()方法時自動地開啟一個事務來進行更新。另外,LINQ to SQL也允許你顯示地聲明并使用你自己的事務處理對象(在.Net2.0中介紹的一個特性)。這使得將LINQ to SQL代碼和現有的數據訪問代碼集成變得更加容易。也意味著你可以將一個非數據庫資源添加到數據庫中――例如,你可以發送一條MSMQ消息,更新文件系統(用新的事務文件系統支持)等――并且將所有的這些工作放到同你用LINQ to SQL更新你數據庫的一個事務中。
Validation and Business Logic
驗證和業務邏輯
?
One of the important things developers need to think about when working with data is how to incorporate validation and business rule logic.? Thankfully LINQ to SQL supports a variety of ways for developers to cleanly integrate this with their data models.?
開發者在跟數據打交道時需要考慮的一個重要的事情就是如何將驗證和業務邏輯結合起來。幸運的是,LINQ to SQL支持開發者清晰地將它們集成在數據模型中的各種各樣的方法。
LINQ to SQL enables you to add this validation logic once - and then have it be honored regardless of where/how the data model you've created is used.? This avoids you having to repeat logic in multiple places, and leads to a much more maintainable and clean data model.?
?
LINQ to SQL使得你添加一次這些驗證邏輯――然后你就可以不用管你生成的數據模型如何被使用,也不用管在何處被使用。這避免了你在我處來重復你的驗證規則,而且使得數據模型更具有可維護性和簡潔性。
?
Schema Validation Support
架構驗證的支持
When you define your data model classes using the LINQ to SQL designer in VS 2008, they will by default be annotated with some validation rules inferred from the schema of the tables in the database.
當使用VS2008中的LINQ to SQL設計器來定義數據模型為時,它們會被默認地加上從數據表中反映出來的驗證規則。
?
The datatypes of the properties in the data model classes will match the datatypes of the database schema.? This means you will get compile errors if you attempt to assign a boolean to a decimal value, or if you attempt to implicitly convert numeric types incorrectly.
數據模型類中的屬性的數據類型要和數據庫中的數據項的數據類型相一致。這意味著如果你試圖將一個boolean類型賦值給一個decimal類型的值,或者錯誤的隱示地轉換一個數據類型時,你就會得到一個編譯錯誤。
If a column in the database is marked as being nullable, then the corresponding property in the data model class created by the LINQ to SQL designer will be a nullable type.? Columns not marked as nullable will automatically raise exceptions if you attempt to persist an instance with a null value.? LINQ to SQL will likewise ensure that identity/unique column values in the database are correctly honored.
如果數據庫中的一列被標志為可空,那么數據模型類相應的屬性將是一個可空的類型。如果你試圖對沒有被標為可空的列賦空值,將會自動拋出異常。 LINQ to SQL 將同樣確保標識/唯一列被正確的賦值。
You can obviously use the LINQ to SQL designer to override these default schema driven validation settings if you want - but by default you get them automatically and don't have to take any additional steps to enable them.? LINQ to SQL also automatically handles escaping SQL values for you - so you don't need to worry about SQL injection attacks when using it.
如果你樂意的話,你可以使用LINQ to SQL 設計器覆蓋默認的框架驗證設置。但是在默認情況下,這是自動的并不需要額外的步驟來啟用它。LINQ to SQL 也會為你自動管理SQL語句-所以在使用時你不必擔心SQL注入。
?
Custom Property Validation Support
自定義屬性驗證支持
Schema driven datatype validation is useful as a first step, but usually?isn't enough for real-world scenarios.?
數據庫框架驗證作為第一步非常有用,但是在實際的場景中并不足夠。
Consider for example a scenario with our Northwind database where we have a "Phone" property on the "Customer" class which is defined in the database as an nvarchar.? Developers using LINQ to SQL could write code like below?to?update it using a valid telephone number:?
例如考慮這一場景,"Customer"類有一個"phone"的屬性,被定義為NVarchar類型,開發者編寫如下代碼,用一個合法的電話號碼來對它進行更新:
The challenge that we will run into with our application, however, is that the below code is also legal from a pure SQL schema perspective (because it is still a string even though it is not a valid phone number):
然而,這種更新在程序中是行得能的,從SQL語句上來說,如下代碼依然是合法的(因為它依然是一個字符串,雖然不是一個電話號碼)
To prevent bogus phone numbers from being added into our database, we can add a custom property validation rule to our Customer data model class.? Adding a rule to validate phone numbers using this feature is really easy.? All we need to-do is to?add a new partial class to our project that defines the method below:
為避免錯誤的號碼插入到數據庫中,我們可以向Customer數據類型類中加入自定義的屬性驗證規則。用這個特性來添加一條對電話號碼的驗證規則確實非常簡單。我們所需要做的是在項目中加一個新的部分類來定義以下方法。:
?
The code above takes advantage of two characteristics of LINQ to SQL:
以上代碼利用了LINQ to SQL 兩個特性:
1) All classes created by the LINQ to SQL designer are declared as "partial" classes - which means that developers can easily add additional methods, properties, and events to them (and have them live in separate files).? This makes it very easy to augment the data model classes and DataContext classes created by the LINQ to SQL designer with validation rules and additional custom helper methods that you define.? No configuration or code wire-up is required.
1) LINQ to SQL 設計器生成的類都被聲明為"局部"類 -這意味著開發者可以向這些總局類中很方便的增加方法,屬性,及事件。因此驗證規則和用戶自定義的輔助方法可以很方便的加入數據模型類和DataContext類中。不需要設置或者代碼綁定。
?
2) LINQ to SQL exposes a number of custom extensibility points in its data model and DataContext classes that you can use to add validation logic before and after things take place.? Many of these extensibility points utilize a new language feature called "partial methods" that is being introduced with VB and C# in VS 2008 Beta2.? Wes Dyer from the C# team has a good explanation?of how partial methods works in this blog post here.
2) LINQ to SQL 揭示了數據模型類及DataContext類中很多用戶可擴展的地方,在這些地方可以添加驗證邏輯??蓴U展的地方利用了一個新的語言特性,稱之為“部分方法”,這是VS2008Beta2 VB和C#引入的。Wes Dyer 在他的日志中對“部分方法”是如何工作的有很好的解釋(here.)。
?
In my validation example above, I'm using the OnPhoneChanging partial method that is executed anytime someone programmatically sets the "Phone" property on a Customer object.? I can use this method to validate the input however I want (in this case I'm using a regular expression).? If everything passes successfully, I just return from the method and LINQ to SQL will assume that the value is valid.? If there are any issues with the value, I can raise an exception within the validation method - which will prevent the assignment from taking place.
在以上驗證的示例中,我使用 OnPhoneChanging 部分方法,此方法將在程序設置“Customer”對象的“Phone”屬性時執行。 如果我想的話我可以使用這個方法來驗證輸入—(在此使用正則表達式)如果一切正確,將從此方法返回而且LINQ to SQL 將認為該值合法。如果有什么錯誤發生,在驗證方法中拋出一個異常-這將阻止賦值。
Custom?Entity Object Validation Support
自定義實體對象驗證支持
?
Property level validation as used in the scenario above is very useful for validating individual properties on a data model class.? Sometimes, though, you want/need to validate multiple property values on an object against each other.?
以上場景中的屬性級驗證對驗證數據模型類的彼此獨立的屬性非常有用。有時,你需要驗證互相作用的多個屬性的值。
Consider for example a scenario with an Order object where you set both the "OrderDate" and the "RequiredDate" properties:
例如,設置訂單對象的 "OrderDate" 和 "RequiredDate" 屬性:
?
The above code is legal from a pure SQL database perspective - even though it makes absolutely no sense for the required delivery date of the new?order to be entered as yesterday.?
上面代碼對于SQL數據庫來說是合法的- 盡管將傳遞的時間設置為訂單時間的昨天是沒有任何意義的。
The good news is that LINQ to SQL in Beta2 makes it easy for us to add custom entity level validation rules to guard against mistakes like this from happening.? We can add a partial class for our "Order" entity and implement the OnValidate() partial method that will be invoked prior to the entity's values being persisted into the database.? Within this validation method we can then access and validate all of the data model class properties:
幸好,在LINQ to SQLBeta2 版本中,通過增加自定義實體級驗證規則可以防止此類錯誤的發生。我們可以給“Order”實體增加一個部分類并且實現OnValidate()的部分方法, 此方法將在實體值被保存在數據庫中之前調用。在此驗證方法中我們可以訪問和驗證數據模型類所有的屬性。
Within this validation method I can check any of the entity's property values (and even obtain read-only access to its associated objects), and raise an exception as needed if the values are incorrect.? Any exceptions raised from the OnValidate() method will abort any changes from being persisted in the database, and rollback all other changes in the transaction.
在驗證方法中可以檢查實體的屬性值(甚至只讀訪問其關聯的對象),如果值不合法的話將拋出異常。任何拋出的異常將中止保存到數據庫,并且回滾同一事務中其他的改動。
Custom?Entity Insert/Update/Delete Method Validation
自定義實體插入/更新/刪除方法驗證
?There are times when you want to add validation logic that is specific to insert, update or delete scenarios.? LINQ to SQL in Beta2 enables this by allowing you to add a partial class to extend your DataContext class and then implement partial methods to customize the Insert, Update and Delete logic for your data model entities.? These methods will be called automatically when you invoke SubmitChanges() on your DataContext.
? 經常你需要的驗證邏輯不單單是在獨立的插入/更新/刪除操作中。LINQ to SQL Beta2允許你將“局部方法”添加到DataContext類中來為你的添加更新和刪除邏輯添加自定義的驗證。這些方法在調用SubmitChanges()時將會被自動調用。
You can add appropriate validation logic within these methods?- and if it passes then tell LINQ to SQL to continue with persisting the relevant changes to the database (by calling the DataContext's "ExecuteDynamicXYZ" method):
在這些方法中,你可以加入適當的驗證邏輯。 - 如果驗證邏輯通過,它將通知 LINQ to SQL保存相關的改動到數據庫。 (通過調用DataContext的"ExecuteDynamicXYZ" 方法):
What is nice about adding the above methods is that the appropriate ones are automatically invoked regardless of the scenario logic that caused the data objects to be created/updated/deleted.? For example, consider a simple scenario where we create a new Order and associate it with an existing Customer:
一個比較好的地方是,以上方法在數據對象創建/更新/刪除時自動匹配執行。例如,如下示例, 我們創建一個新的定單關聯到一個存在的客戶。
When we call northwind.SubmitChanges() above, LINQ to SQL will determine that it needs to persist a new Order object, and our "InsertOrder" partial method will automatically be invoked.?
在我們調用Northwind.SubmitChanges() 時,, LINQ to SQL 將決定保存新的定單對象, "InsertOrder"部分方法將被自動調用。
Advanced: Looking at the Entire Change List for the Transaction
高級:事務中全部的發動列表
There are times when adding validation logic can't be done purely by looking at individual insert/update/delete operations - and instead you want to be able to look at the entire change list of operations that are occurring for a transaction.?
經常你需要的驗證邏輯不單單是在獨立的插入/更新/刪除操作中。反而,你需要檢查在同一事務中發生的所有改動。
Starting with Beta2 of .NET 3.5, LINQ to SQL now enables you to get access to this change list by calling the public DataContext.GetChangeList() method.? This will return back a ChangeList object that exposes collections of each addition, removal and modification that has been made.?
從 .NET 3.5 Beta2,LINQ to SQL開始,你可以通過調用DataContext.GetChangeList() 訪問所有的改變列表。此方法返回一個ChangeList 對象,該對象包含了增加,刪除及修改的集合。
One approach you can optionally employ for advanced scenarios is to sub-class the DataContext class and override its SubmitChange() method.? You can then retrieve the ChangeList() for the update operation and perform any custom validation you want prior to executing it:
在更高級的場景中,你可以繼承DataContext類,重寫SubmitChange()方法。在保存到數據庫之前,通過獲取更新操作的ChangeList()進行自定義的驗證
?
The above scenario is a somewhat advanced one - but it is nice to know that you always have the ability to drop-down and take advantage of it if needed.
以上是一個高級的場景--但是最好你要在需要的時候 ,你可以實現并能利用它。
Handling Simultaneous Changes with Optimistic Concurrency
樂觀并發控制
One of the things that developers need?to think about in multi-user database systems is how to handle simultaneous updates of the same data in the database.? For example, assume two users retrieve a product object within an application, and one of the users changes the ReorderLevel to 0 while the other changes it to 1.? If both users then attempt to save the product back to the database, the developer needs to decide how to handle the change conflicts.?
開發者需要關心的一點是,在多用戶的數據庫系統中,如何處理同一數據同時更新。例如,假定兩個用在以各應用中獲取一個產品對象,其中一個用戶設置RecorderLevel為0,而另外一個用戶設置為1。如果兩個用戶試圖將此產品保存到數據庫,開發者需要決定如何處理這個改動的沖突。
?One approach is to just "let the last writer win" - which means that the first user's submitted value will be lost without the end-users realizing it.? This is usually considered a poor (and incorrect) application experience.?
一種解決方法是 "最后寫入者贏" - 這意味著第一位用戶沒有的到提示的情況下,其提交的值將被丟掉。通常這被認為是一個不好(不正確)的應用經驗。
Another approach?which LINQ to SQL supports is to use an optimistic concurrency model?- where?LINQ to SQL will automatically detect if the original values in the database have been updated by someone else prior to the new values being persisted.? LINQ to SQL can then provide a conflict list of changed values to the developer and enable them to either reconcile the differences or provide the end-user of the application with UI to indicate what they want to-do.?
另外一個方法是 LINQ to SQL 支持樂觀并發模型。 -? 在保存新值之前,LINQ to SQL 將自動探測原值已被其他人修改.? LINQ to SQL 然后可以提供一個改變值得沖突列表,這樣開發者或者協調數值之間的差距,或者在UI中提示用戶要如何處理。
I'll cover how to use optimistic concurrency with LINQ to SQL in a future blog post.
在以后的帖子中我將講解如何用LINQ to SQL處理樂觀并發沖突。
Using SPROCs or Custom SQL?Logic for Insert/Update/Delete Scenarios
用存儲過程或者自定義的SQL語句來插入/更新/刪除記錄的情景
?
One of the questions that developers (and especially DBAs) who are used to writing SPROCs with custom SQL usually ask when seeing LINQ to SQL for the first time is - "but how can I have complete control of the underlying SQL that is executed?"?
?
那些過去用SQL語句寫自定義的存儲過程(尤其DBA們)在第一次見到LINQ to SQL時經常問的一個問題是—"可是我如何完全地控制它執行的SQL語句?"
?
The good news is that LINQ to SQL has a pretty flexible model that enables developers to override the dynamic SQL that is automatically executed by LINQ to SQL, and instead call custom insert, update, delete SPROCs that they (or a DBA) define themselves.?
?
有一個好的消息,就是LINQ to SQL有一個非常之靈活的模型,該模型允許開發者們重寫LINQ to SQL動態生成的SQL語句,用他們自定義的插入/更新/刪除的存儲過程來替代那些生成的SQL語句.
?
What is really nice is that you can start off by defining your data model and have LINQ to SQL automatically handle the insert, update, delete SQL logic for you.? You can then at a later point customize the data model to use your own custom SPROCs or SQL for updates - without having to change any of the application logic that is using your data model, nor?would you?have to change any of the validation or business rules logic supporting it (all of this stays the same).? This provides a lot of flexibility in how you build your application.
?
真正好的一點是你可以通過定義你的數據模型來讓LINQ to SQL自動的處理插入/更新/刪除的SQL邏輯。你可以為更新定義一個你自己的存儲過程或者SQL語句-這樣在以后更新應用程序時你可以既不必去更改應用了你的數據模型的應用程序的邏輯,又不必去更改任何的驗證或者業務邏輯(所有的這些使用原有的即可)。這在你如何構建應用程序上提供了很大的靈活性。
?
I'll cover how to customize your data models to use SPROCs or custom SQL in a future blog post.
在接下來的一篇帖子中我將會講解一下如何自定義你的數據模型來使用存儲過程或者自定義的SQL語句。
?
?
Summary
?
總結
?
Hopefully the above post provides a good summary of how you can easily use LINQ to SQL to update your database, and cleanly integrate validation and business logic with your data models.? I think you'll find that LINQ to SQL can dramatically improve your productivity when working with data, and enable you to write extremely clean object-oriented data access code.
?
希望上面這篇帖子給你提供了如何用LINQ to SQL方便地更新你的數據庫的,如何清晰地將你的驗證及業務邏輯和你的數據模型結合起來的一個好的概述。我想你會發現,在和數據打交道時,LINQ to SQL會極大地提高你的生成力,并且能夠讓你寫出非常整潔的面向對象的數據訪問的代碼。
?
In upcoming blog posts in this series I'll cover the new <asp:linqdatasource> control coming in .NET 3.5, and talk about how you can easily build data UI in ASP.NET that takes advantage of LINQ to SQL data models. I'll also cover some more specific LINQ to SQL programming concepts including optimistic concurrency, lazy and eager loading, table mapping inheritance, custom SQL/SPROC usage, and more.
?
在本系列的下面的帖子中,我將講述一下在.Net3.5中的新增的<asp:linqdatasource>控件,并且講一下在使用LINQ to SQL的數據模型的情況下在ASP.NET中建立一個數據的UI是多么地方便!我會更近一步地講術一下LINQ to SQL的編程思想,包括優化并發沖突,延遲和提前加載,表映射的繼承,自定義的存儲過程的使用等。
Hope this helps,
希望這些能對你有所幫助
Scott
轉載于:https://www.cnblogs.com/hanxianlong/archive/2007/11/19/962696.html
總結
以上是生活随笔為你收集整理的ScottGu之博客翻译-LINQ to SQL第四部分,更新数据库 LINQ to SQL (Part 4 - Updating our Database)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WebSphere Applicatio
- 下一篇: 获取某年某月的第一天和最后一天的Sql