Lập trình ứng dụng nâng cao (phần 8) pot

50 439 0
Lập trình ứng dụng nâng cao (phần 8) pot

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

332 | Chapter 14: Working with XML // Simple customer class public class Customer { [XmlAttribute( )] public string FirstName { get; set; } [XmlIgnore( )] public string LastName { get; set; } public string EmailAddress { get; set; } // Overrides the Object.ToString( ) to provide a // string representation of the object properties. public override string ToString( ) { return string.Format("{0} {1}\nEmail: {2}", FirstName, LastName, EmailAddress); } } // Main program public class Tester { static void Main( ) { Customer c1 = new Customer { FirstName = "Orlando", LastName = "Gee", EmailAddress = "orlando0@hotmail.com" }; //XmlSerializer serializer = new XmlSerializer(c1.GetType( )); XmlSerializer serializer = new XmlSerializer(typeof(Customer)); StringWriter writer = new StringWriter( ); serializer.Serialize(writer, c1); string xml = writer.ToString( ); Console.WriteLine("Customer in XML:\n{0}\n", xml); Customer c2 = serializer.Deserialize(new StringReader(xml)) as Customer; Console.WriteLine("Customer in Object:\n{0}", c2.ToString( )); Console.ReadKey( ); } } } Output: Customer in XML: <?xml version="1.0" encoding="utf-16"?> Example 14-6. Customizing XML serialization with attributes (continued) XML Serialization | 333 The only changes in this example are a couple of added XML serialization attributes in the Customer class: [XmlAttribute( )] public string FirstName { get; set; } The first change is to specify that you want to serialize the FirstName property into an attribute of the Customer element by adding the XmlAttributeAttribute to the property: [XmlIgnore( )] public string LastName { get; set; } The other change is to tell XML serialization that you in fact do not want the LastName property to be serialized at all. You do this by adding the XmlIgnoreAttribute to the property. As you can see from the sample output, the Customer object is serialized exactly as we asked. However, you have probably noticed that when the object is deserialized, its LastName property is lost. Because it is not serialized, the XmlSerializer is unable to assign it any value. Therefore, its value is left as the default, which is an empty string. The goal is to exclude from serialization only those properties you don’t need or can compute or can retrieve in other ways. Runtime XML Serialization Customization Sometimes it may be necessary to customize the serialization of objects at runtime. For instance, your class may contain an instance of another class. The contained class may be serialized with all its properties as child elements. However, you may want to have them serialized into attributes to save some space. Example 14-7 illus- trates how you can achieve this. <Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" FirstName="Orlando"> <EmailAddress>orlando0@hotmail.com</EmailAddress> </Customer> Customer in Object: Orlando Email: orlando0@hotmail.com Example 14-7. Customizing XML serialization at runtime using System; using System.IO; using System.Reflection; using System.Xml.Serialization; Example 14-6. Customizing XML serialization with attributes (continued) 334 | Chapter 14: Working with XML namespace Programming_CSharp { // Simple customer class public class Customer { public string FirstName { get; set; } public string LastName { get; set; } public string EmailAddress { get; set; } // Overrides the Object.ToString( ) to provide a // string representation of the object properties. public override string ToString( ) { return string.Format("{0} {1}\nEmail: {2}", FirstName, LastName, EmailAddress); } } // Main program public class Tester { static void Main( ) { Customer c1 = new Customer { FirstName = "Orlando", LastName = "Gee", EmailAddress = "orlando0@hotmail.com" }; Type customerType = typeof(Customer); XmlAttributeOverrides overrides = new XmlAttributeOverrides( ); foreach (PropertyInfo prop in customerType.GetProperties( )) { XmlAttributes attrs = new XmlAttributes( ); attrs.XmlAttribute = new XmlAttributeAttribute( ); overrides.Add(customerType, prop.Name, attrs); } XmlSerializer serializer = new XmlSerializer(customerType, overrides); StringWriter writer = new StringWriter( ); serializer.Serialize(writer, c1); string xml = writer.ToString( ); Console.WriteLine("Customer in XML:\n{0}\n", xml); Customer c2 = serializer.Deserialize(new StringReader(xml)) as Customer; Console.WriteLine("Customer in Object:\n{0}", c2.ToString( )); Example 14-7. Customizing XML serialization at runtime (continued) XML Serialization | 335 The Customer class in this example has no custom XML serialization attributes. Therefore, all its properties are serialized into child elements, as you have seen in previous examples. When an instance of it is serialized at runtime in the main func- tion, we use a combination of reflection and advanced serialization techniques to ensure that the properties are serialized into attributes instead. In .NET XML serialization, you instruct the serialization engine to override its default behavior with your custom requirements. Because you are going to use the Customer type a lot, you store it locally so that it you can use it later: Type customerType = typeof(Customer); To specify your custom requirements, you use the XmlAttributeOverrides class: XmlAttributeOverrides overrides = new XmlAttributeOverrides( ); foreach (PropertyInfo prop in customerType.GetProperties( )) { XmlAttributes attrs = new XmlAttributes( ); attrs.XmlAttribute = new XmlAttributeAttribute( ); overrides.Add(customerType, prop.Name, attrs); } The first step is to create a new XmlAttributeOverrides instance. You can now use . NET reflection to go through all the properties of the target class, using its GetProperties method. For each property, you override its default serialization behav- ior by adding an XmlAttributes object to the XmlAttributeOverrides object. To spec- ify that you want to serialize the property as an attribute, you assign an XmlAttributeAttribute object to the XmlAttributes.XmlAttribute property. This is the equivalent of adding the XmlAttributeAttribute to a property at design time, as you did in the last example. The XmlAttributeOverrides.Add method takes three input parameters. The first is the type of the object, the second is the name of the property, and the last is the cus- tomer serialization behavior. Console.ReadKey( ); } } } Output: Customer in XML: <?xml version="1.0" encoding="utf-16"?> <Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" FirstName=" Orlando" LastName="Gee" EmailAddress="orlando0@hotmail.com" /> Customer in Object: Orlando Gee Email: orlando0@hotmail.com Example 14-7. Customizing XML serialization at runtime (continued) 336 | Chapter 14: Working with XML To ensure that the XML serializer use the customer serialization overrides, you must pass in the overrides object to its constructor: XmlSerializer serializer = new XmlSerializer(customerType, overrides); The rest of this example stays unchanged from the last example. You can see from the sample output that all the properties are indeed serialized into attributes instead of child elements. When the object is deserialized, the customer overrides are also recognized and the object is reconstructed correctly. 337 Chapter 15 CHAPTER 15 Putting LINQ to Work15 LINQ may be the most anticipated, most exciting (and to some, most feared) feature in C# 3.0. The previous two chapters were, in large measure, a necessary introduc- tion, an appetizer to whet your appetite and get you ready for the main meal: using LINQ to retrieve meaningful data in production applications. Before we begin, let’s be clear: your DBA is terrified of LINQ, and not just as a mat- ter of job security. Improperly used, LINQ has the ability to put queries into the hands of inexperienced, untrained goofballs (us) who know little or nothing about writing efficient queries, and who will bring carefully honed data-intensive enterprise systems to their knees (fun, eh?). OK, I said it out loud, so let’s all stop panicking. As with all programming, the trick is to write the program, get it working, and then optimize. It may be that after you have your program up and working (and profiled), you’ll discover that there are some places that you’ve used LINQ that you’d be bet- ter off using stored procedures running within your database (that’s what databases do for a living), but we don’t know that a priori, and the advantages of LINQ are so tremendous (e.g., the ability to use an object-oriented unified syntax to access all your data regardless of source) that it cries out for a “code now, optimize later if needed” approach. The two most common sources you’ll use LINQ with are, no doubt, SQL and XML, but they are certainly not the only sources of data. You may well find yourself retriev- ing data from: • Files • Flat databases • Mail messages • Web services • Legacy systems • In memory data structures 338 | Chapter 15: Putting LINQ to Work And most exciting are sources you haven’t anticipated yet. With the understanding of LINQ fundamentals you gained in Chapter 13, and the grounding in XML you gained in Chapter 14, you are now just about ready to dig in and put LINQ to work. Getting Set Up Examples in this section use the SQL Server 2005 Adventure Works LT sample data- base. To set up this database, download it from: http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases. aspx?ReleaseId=4004 Please note that although this database is a simplified version of the more comprehensive AdventureWorks, the two are quite different, and the examples in this chapter will not work with the full AdventureWorks database. Please select the AdventureWorksLT MSI package applicable for your platform—32-bit, x64, or IA64. If SQL Server is installed in the default directory, install the sample database to C:\Program Files\ Microsoft SQL Server\MSSQL.1\MSSQL\Data\. Otherwise, install the database to the Data subdirectory under its installation directory. If you are using SQL Server Express included in Visual Studio 2008, you will need to enable the Named Pipes protocol: 1. Open SQL Server Configuration Manager under Start ➝ All Programs ➝ Microsoft SQL Server 2005 ➝ Configuration Tools ➝ SQL Server Configuration Manager. 2. In the left pane, select SQL Server Configuration Manager (Local) ➝ SQL Server 2005 Network Configuration ➝ Protocols for SQLEXPRESS. 3. In the right pane, right-click the Named Pipes protocol and select Enable, as shown in Figure 15-1. 4. In the left pane, select SQL Server 2005 Services, then right-click SQL Server (SQLEXPRESS), and select Restart to restart SQL Server, as shown in Figure 15-2. 5. Attach the sample database to SQL Server Express using one of the following methods: a. If you already have SQL Server Client tools installed, open SQL Server Management Studio under Start ➝ All Programs ➝ Microsoft SQL Server 2005 ➝ SQL Server Management Studio and connect to the local SQL Server Express database. LINQ to SQL Fundamentals | 339 b. Download SQL Server Express Management Studio from the Microsoft SQL Server Express page (http://msdn2.microsoft.com/en-us/express/bb410792. aspx), and install it on your machine. Then, open it and connect to the local SQL Server Express database. 6. In the left pane, right-click Databases and select Attach (see Figure 15-3). 7. On the Attach Databases dialog click Add. 8. Click OK to close this dialog, and OK again to close the Attach Database dialog. LINQ to SQL Fundamentals To begin, open Visual Studio, and create a new application named “Simple Linq to SQL” as a console application. Once the IDE is open, click on View, and open the Server Explorer and make a connection to the AdventureWorksLT database, and test that connection. Figure 15-1. Enabling the Named Pipes protocol in SQL Server 2005 Express Figure 15-2. Restarting SQL Server 2005 Express 340 | Chapter 15: Putting LINQ to Work With that in place, you are ready to create a program that uses LINQ to connect your SQL database. You’ll need to include the System.Data.Linq namespace in the references for your project as shown in Figure 15-4 so that the last two using state- ments will compile. This will also create the mapping between each class property and the correspond- ing database column: public class Customer { Figure 15-3. Attaching the database to SQL Server 2005 Express LINQ to SQL Fundamentals | 341 [Column] public string FirstName { get; set; } [Column] public string LastName { get; set; } [Column] public string EmailAddress { get; set; } Complete analysis follows Example 15-1. Figure 15-4. Adding a reference to System.Data.Linq Example 15-1. Simple LINQ to SQL using System; using System.Data.Linq; using System.Data.Linq.Mapping; using System.Linq; namespace Simple_Linq_to_SQL { // customer class [Table(Name="SalesLT.Customer")] public class Customer { [Column] public string FirstName { get; set; } [Column] public string LastName { get; set; } [Column] public string EmailAddress { get; set; } // Overrides the Object.ToString( ) to provide a // string representation of the object properties. public override string ToString( ) [...]... AdventureWorksAddressDataContext include Customers, Addresses, and CustomerAddresses One side effect of this convention is that it would be a good idea to name your database tables in singular form to avoid potential confusion in your code By default, the LINQ to SQL designer names the generated data classes the same as the table names If you use plural table names, the class names will be the same as the... type-safe, in C#, this is entirely type-safe; the compiler imputes the type based on the query Next, we create an XElement named customerXml: XElement customerXml = new XElement("Customers"); Here’s another potentially confusing aspect We’ve given the C# XElement an identifier, customerXml, so that we can refer to it in C# code, but when we instantiated the XElement, we passed a name to the constructor (Customers) . convention is that it would be a good idea to name your database tables in singular form to avoid potential confu- sion in your code. By default, the LINQ to SQL designer names the generated data

Ngày đăng: 07/07/2014, 05:20

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan