- Page 1:Create a Silverlight 3 sample project
- Page 7: Add a data model and domain service for the Data Model
- Page 6: Silverlight user interface and basic background code programming
- Page 1: Write application logic
- Page 1: operations and statements of Common Services
- Page 1: running results
- Page 1: important supplements to related domains
- Page 1: Full Text Summary
Show all
Text Tag: Visual Studio, Microsoft Web development, Ria Silverlight
[It168]In the process of developing a RIA Data Center Application Based on Silverlight technology, there is a awkward problem: No matter what data access technology you choose, No matter what traditional Web service or WCF Service, or ADO. NET data service technology requires you to manually add references to these services from the Silverlight project and perform more manual coding. That is to say, data access is still a headache for such Ria applications.
In response to the above problems, Microsoft launched Silverlight 3.0, and another version of RIA services-July 2009 preview.
Crud operations are the most typical operations in data access to the server. To this end, the RIA Service provides off-the-shelf support, including the corresponding standardization requirements for the definition of domain service methods. However, in some cases, we often use a large number of non-Crud operations, such as conditional computing and General Service-type method computing. To this end, the RIA Service also provides relevant provisions.
In this article, we will use a simple example to discuss the definition methods in Silverlight 3ria Service programming and the programming skills of common services and related precautions.
Create a Silverlight 3 sample project
(1) Open Visual Studio 2008 and select the "file | new | project" menu command to open the "new project" dialog box.
(2) Select the "Silverlight application" template, create a Silverlight 3 Project, and name it s3riacustomsample.
(3) Click "OK" to go to the next step and select the website hosting the Silverlight application. Select ASP. NET web application project from the web project type drop-down list box ". Select the "Enable. Net Ria Services" Check button at the bottom of the dialog box to add the RIA framework support to the current solution.
Now, we have created two projects:
1. s3riacustomsample-This project contains the Silverlight code. This project is called a client project, which is the Client layer of the application we created.
2. s3riacustomsample. Web-This project contains ASP. NET web application code. This project is called a server project, which is the middle layer of the application we created.
At this time, a basic Silverlight 3 sample project framework is designed.
Click here to express your opinion> [Some netizens have already expressed their views]
Add a LINQ to SQL data model to a web project
(1) Right-click the WEB Project s3riacustomsample. Web and choose "add | new item" from the shortcut menu. In the "Add new project" dialog box that appears, select the "LINQ to SQL classes" template, use the default name dataclasses1.dbml, and click "add" to exit.
For ease of debugging, we use the SQL Server 2008 Sample Database adventureworks provided by Microsoft. Add the adventureworks instance database connection operation in the server resource manager. The operation is not described here, but it is assumed that the connection has been created by the user.
(2) After exiting the "Add new project" dialog box above, the system will automatically open the LINQ to SQL designer. Now, we can add the object corresponding to the database table. To solve this problem, you only need to find the added adventureworks sample database in the server resource manager, and drag the product table from the server resource manager to the internal of the linq to SQL designer, finally, save the generated file.
(3) Finally, select "generate | regenerate SOLUTION ".
Create a domain service corresponding to the LINQ to SQL data model
(1) Right-click the WEB Project s3riacustomsample. Web and choose "add | new item" from the shortcut menu. In the "Add new project" dialog box that appears, select the "Domain Service Classes" template to add a domain service, enter the name catalog. CSL, and click "add" to exit.
(2) The "Add new domain service class" dialog box appears later. Select the product entity in the dialog box, and make sure that the "enable editing" Check button is selected. Finally, select the "generate associated classes for metadata" Check button at the bottom of the dialog box to ensure that the associated classes are generated in metadata.
(3) Finally, select "generate | regenerate SOLUTION ".
Note: Some codes in the above Code have been commented out, and only basic product information data has been created to load the code. More code analysis will be provided later.
Click here to express your opinion> [Some netizens have already expressed their views]
Silverlight user interface and basic background code programming
In fact, from the perspective of layering, the client Silverlight project can be further divided into several sub-layers. For example, the. XAML file can be seen as the top display layer, and the corresponding background code file. XAML. CS is another layer.
The main page file automatically generated by the Silverlight 3 project is mainpage. XAML. Open the file and enter the following code:
<Usercontrol
Xmlns: Data = "CLR-namespace: system. Windows. controls; Assembly = system. Windows. Controls. Data" X: class = "s3riacustomsample. mainpage"
Xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Xmlns: x = "http://schemas.microsoft.com/winfx/2006/xaml"
Xmlns: D = "http://schemas.microsoft.com/expression/blend/2008"
Xmlns: MC = "http://schemas.openxmlformats.org/markup-compatibility/2006"
MC: ignorable = "D" D: designwidth = "Auto" D: designheight = "Auto">
<Grid X: Name = "layoutroot">
<Stackpanel orientation = "vertical">
<Data: DataGrid isreadonly = "true" name = "productsgrid" Height = "Auto" width = "Auto"
Selectionchanged = "maid"/>
<Stackpanel orientation = "horizontal">
<Textblock text = "competitor's price" margin = "2"/>
<Textblock X: Name = "compprice" margin = "2"/>
</Stackpanel>
<Stackpanel orientation = "horizontal">
<Button click = "button_click" content = "discount" X: Name = "discountbutton" margin = "2"/>
<Textbox X: Name = "discountpercent" text = "10" margin = "2, 2"/>
<Textblock text = "%" margin = ","/>
</Stackpanel>
</Stackpanel>
</GRID>
</Usercontrol>
The above XAML code is very simple and will not be repeated.
The content of the corresponding background code file mainpage. XAML. CS is as follows:
Using system;
Using system. Collections. Generic;
Using system. LINQ;
Using system. net;
Using system. windows;
Using system. Windows. controls;
Using system. Windows. documents;
Using system. Windows. input;
Using system. Windows. Media;
Using system. Windows. Media. animation;
Using system. Windows. shapes;
// The following is the newly added namespace reference
Using system. Windows. Ria. Data;
Using RIA = s3riacustomsample. Web;
Namespace s3riacustomsample
{
Public partial class mainpage: usercontrol
{
Ria. Catalog catalog = new Ria. Catalog (); // create a catalog object instance
Public mainpage ()
{
Initializecomponent ();
Productsgrid. itemssource = catalog. Products;
VaR query = from P in catalog. getproductquery ()
Where p. listprice> 3000 select P;
Catalog. Load (query); // load the product data that meets the requirements to the DataGrid Control
}
Private void button_click (Object sender, routedeventargs E)
{
Ria. Product selectedproduct = (RIA. Product) productsgrid. selecteditem;
If (selectedproduct! = NULL ){
// Int percentage = int. parse (discountpercent. Text );
// Selectedproduct. discountproduct (percentage );
// Catalog. submitchanges ();
}
}
Private void datagrid_selectionchanged (Object sender, selectionchangedeventargs e ){
Ria. Product selectedproduct = (RIA. Product) productsgrid. selecteditem;
If (selectedproduct! = NULL ){
// Catalog. getcompetitorsprice (selectedproduct,
// (Invokeoperation) =>
//{
// Compprice. Text = invokeoperation. value. tostring ();
//}, Null );
}
}
}
Click here to express your opinion> [Some netizens have already expressed their views]
Write application logic
The business logic layer in this case is provided by the host web project. In addition, in the RIA Service programming environment, the logic part of the application is mainly implemented by the domain service method.
Now, the above user interface only achieves the loading and display of basic (or original) Product Data. Next, we will add some features: discounts for selected products and displaying competitors' prices. We need to reduce the price of a product selected for a discount by several percentage points. This data is provided by the user. To show the price of competitors, we need to perform an out-of-band Server query. In actual application development, such queries may be quite complex, such as querying another website to get the best price and wait. For simplicity, we will only return a price below the price of 5%.
Obviously, to implement the above operations, you need to write a domain service method-custom method that is not a basic CRUD operation.
(1) custom methods
The custom method is to use some additional application logic to implement operations other than basic CRUD operations (create, update, and delete) during asynchronous domain operations.
Custom methods have the same change tracking and delayed execution characteristics as basic CRUD operations. This means that the changes made on the client will not be submitted to the server immediately, but will be completed after the domaincontext. submitchanges () method is called.
(2) Declaration of custom methods
There are two ways to mark a method defined in domainservice as a custom method:
Common Conventions: ① return the void type; ② use an object as the first parameter; ③ not an expression of the creation, update, or deletion conventions.
Modify the customattribute Attribute before the method.
In the following code snippet, we introduce two methods, but only one is necessary. This code implements a simple discount algorithm. Note: You may have guessed the above prompt that this code should be added to the domainservice catalog.
See the following code:
[Custom]
Public void discountproduct (product, int percentage)
{
This. Context. Product. Attach (product );
Decimal newprice = product. listprice * (1-percentage/100 m );
Product. listprice = newprice; // do logging/reporting here
}
In the code above, the RIA service passes the entity in the current state to the custom method as a parameter. Of course, if you need to use the original entity state, you should use the following code:
This. Changeset. getoriginal (product); click here to express your opinion> [views of some netizens]
(3) usage of custom methods
The client can call the custom method in two ways:
(1) Use the generated domain context and pass it to the object as a parameter:
Catalog. discountproduct (selectedproduct, percentage );
Or:
(2) Use the entity itself for operations:
Selectedproduct. discountproduct (percentage );
(4) General Service Operations ("service operations" for short ")
Compared with other domainservice types discussed earlier, common service operations are more similar to traditional web methods. When the server logic is not suitable for the creation, update, and deletion modes, you can choose to use common service operations. Unlike other domainservice operations, normal service operations are not supported by change tracking or delayed execution. This means that once a method call is made on the client, common service operations are submitted to the server.
(5) General Service Operation statement
Methods without naming conventions are identified as common service operations. To mark a method as a normal service running, use the serviceoperation attribute to mark it. The following sample service operation obtains the price of the competitor associated with the specified product. Note: You may have guessed it by following the preceding prompt. This code should be added to the domainservice catalog.
[Serviceoperation]
Public decimal getcompetitorsprice (product)
{
// Do some kind of price lookup.
Return product. listprice * 0.95 m;
}
The return type of the parameter and serviceoperation must be an entity or a predefined serialization type.
(6) using common services
It should be noted that, like other operations in the RIA service framework, the execution of common service methods is asynchronous. There are three methods to access the return values of common service operations. Developers can:
① Bind directly to invokeoperation. value, as shown in the following figure:
Invokeoperation <decimal> invokeop = catalog. getcompetitorsprice (selectedproduct );
Compprice. Text = invokeop. value. tostring ();
② You can also use the method of passing the callback function, as shown below:
Catalog. getcompetitorsprice (selectedproduct,
(Invokeoperation) =>
{
Compprice. Text = invokeoperation. value. tostring ();
}, Null );
③ You can also use the method of registering the event processor function:
Invokeoperation <decimal> invokeop = catalog. getcompetitorsprice (selectedproduct );
Invokeop. Completed + = new system. eventhandler (invokeop_completed );
Void invokeop_completed (Object sender, system. eventargs E)
{
Invokeoperation <decimal> invokeop = (invokeoperation <decimal>) sender;
Compprice. Text = invokeop. value. tostring ();
}
Click here to express your opinion> [Some netizens have already expressed their views]
Observe running results
Now, you can run the application by removing the comments before the call Methods discountproduct () and getcompetitorsprice () in the mainpage. XAML. CS file. The running snapshot of the sample program at a certain time point is displayed.
Select a product from the control DataGrid, and the corresponding Competitor price will pop up. Then, you can click "discount" to lower the price.
Click here to express your opinion> [Some netizens have already expressed their views]
Important supplements
In Ria Service programming, it is very important to abide by the established domain operation method conventions. Its significance lies in:
Developers can invest less effort.
Provide consistent and aesthetic programming experience.
The general-purpose domain-driven language is implemented, and the code readability in team development is improved.
(1) Rules applicable to all domain operations
In summary, the rules applicable to all domain operations include:
The domain operation must contain a public modifier.
If the first (or several consecutive) parameter types are Entity types, only one domain operation method is allowed. When the query method returns an ienumberable or iqeryable type, this type represents an entity as long as it is applied to riaservices-related operations. Therefore, to make other domain operations valid, make sure that there is a domain operation method of the query type. In this case, the allowed exception is that the domain operation method that does not use the object type as the parameter will be a valid domain operation method.
Domain operation methods must use serializable types as parameters and return types.
(2) protocol domain operation method programming Convention
1. insert operation
The void type is returned, and there is only one object parameter type.
Naming format: the prefix is insert, add, or create, followed by the object name.
For example:
Public void insertemployee (employee newemployee ){...}
When using the insertattribute, you can use any naming format, for example:
[Insert]
Public void yourfavoritemethodname (employee newemployee ){...}
2. Update operations
The void type is returned, and there is only one object parameter type.
Naming format: the prefix is one of update, change, and modify, followed by the object name.
For example:
Public void updateemployee (employee hangedemployee ){...}
When the updateattribute attribute is used, any naming format can be used, for example:
[Update]
Public void yourfavoritemethodname (employee changedemployee)
3. Delete
The void type is returned, and there is only one object parameter type.
Naming format: the prefix is one of Delete and remove, followed by the object name. For example:
Public void deleteemployee (employee currentemployee)
When deleteattribute is used, any naming format can be used, for example:
[Delete]
Public void yourfavoritemethodname (employee currentemployee)
4. query operations
It can be any method that returns ienumerable <t>, iqueryable <t>, or T type. Here T is the object type. For example:
Public iqueryable <employee> getemployee (){...}
// You can also return an object type instead of the iqueryable/ienumerable type.
Public city getcity (){...}
In addition, you can use the queryattribute to explicitly specify a method as a query operation. For example:
[Query]
Public iqueryable <employee> getemployee (){...}
5. About custom operations
Return the void type. The object type is used as the first parameter of the method, and the method name does not follow the conventions corresponding to the previous crud operations. This facilitates the identification as a custom method, for example:
Public void approveemployee (employee changedemployee ,...)
In addition, you can use the customattribute attribute to explicitly specify a method as a custom operation. For example:
[Custom]
Public void approveemployee (employee changedemployee ,...)
Click here to express your opinion> [Some netizens have already expressed their views]
6. Resolution Method for possible data conflicts in the above operations
Return the bool type. The first three parameters must use the entity type as the first parameter of the method. The fourth parameter must be of the bool type. In addition, the first three parameters correspond to the current object, the initial object, and the object to be saved.
In addition, the method must be preceded by resolve, for example:
Public bool resolveemployee (purchaseorder currentemployee, purchaseorder originalemployee, purchaseorder storeemployee, bool deleteoperation)
Note]
A. To use the above parsing method, you must ensure that an update method exists in advance.
B. In siverlight Ria Service programming, when multiple users update the same record data in the same table at the same time, an exception is thrown. Therefore, it is very important to establish the above Parsing Method for parsing.
7. service operation methods
Only one requirement is that the method name must be prefixed with the serviceoperation attribute. For example:
[Serviceoperation]
Public byte [] getproductimage (){...}
8. About ignoreoperation attributes
In some cases, we may want to explicitly exclude some domain methods, that is, although we have established methods that follow the above conventions, we do not want the system to identify this as a domain method. In this case, We Can prefix these methods with the ignoreoperation attribute. Therefore, the system recognizes this method as a negligible method.
For example:
[Ignoreoperation]
Public void insertemployee (employee newemployee ){...}
[Note] the ignoreoperation attribute can be applied to all domain methods.
Summary
In this article, we use a simple example to discuss the customization methods and common service operations involved in Silverlight 3 RIA development, in addition, it compares typical crud domain operations, custom domain operations, and common service operations. All of these are required in the development of Silverlight 3 Ria.
Obviously, with the help of the RIA service, the data access and related processing of Silverlight programming will be greatly simplified. However, there are also a lot of new knowledge to be updated and learned.