📒
OpenRiaServices
  • Start
  • Prerequisites for Open Ria Services
    • Walkthrough: Installing and Configuring SQL Server 2008 R2 Express with Advanced Services
    • Walkthrough: Installing the AdventureWorks OLTP and LT sample databases
  • Creating Open Ria Services Solutions
    • Walkthrough: Taking a Tour of Open Ria Services
    • Walkthrough: Creating a Open Ria Services Solution
    • Walkthrough: Creating a Open Ria Service with the Code First Approach
    • Walkthrough: Using the Silverlight Business Application Template
    • Walkthrough: Creating a Open Ria Services Class Library
    • Walkthrough: Localizing a Business Application
    • How to: Create a Domain Service that uses POCO-defined Entities
    • How to: Add or Remove a Open Ria Services Link
    • Using the Domain Service Wizard
  • Building Secure Applications with Open Ria Services
  • Deploying and Localizing a Open Ria Services Solutions
    • Troubleshooting the Deployment of a Open Ria Services Solution
    • Troubleshooting the Deployment of a Open Ria Services Solution
    • Walkthrough: Localizing a Business Application
  • Middle Tier
    • Domain Services
      • Walkthrough: Adding Query Methods
      • How to: Add Business Logic to the Domain Service
      • How to: Create a Domain Service that uses POCO-defined Entities
      • How to: Use HTTPS with a Domain Service
    • Data
      • Compositional Hierarchies
      • Presentation Models
      • Inheritance in Data Models
      • Complex Types
      • Shared Entities
      • Walkthrough: Sharing Entities between Multiple Domain Services
      • How to: Add Metadata Classes
      • How to: Validate Data
      • Managing Data Concurrency
    • Shared Code
      • How to: Share Code through Source Files
      • Walkthrough: Creating a Open Ria Services Class Library
  • Silverlight Clients
    • Client Code Generation
    • DomainContext and Operations
    • DomainDataSource
    • Error Handling on the Client
    • Customizing Generated Code
      • How to: Add Computed Properties on the Client
  • Accessing non-Silverlight Clients
    • ASP.NET Clients
    • Walkthrough: Using the Domain Service in ASP.NET Applications
  • Authentication, Roles, and Profiles
    • How to: Enable Authentication in Open Ria Services
    • How to: Enable Roles in Open Ria Services
    • How to: Enable Profiles in Open Ria Services
    • How to: Create a Custom Authorization Attribute
    • Walkthrough: Using Authentication Service with Silverlight Business Application
    • Walkthrough: Using Authentication Service with Silverlight Navigation Application
  • End-to-EndScenarios
    • Walkthrough: Retrieving and Displaying Data From a Domain Service
    • Walkthrough: Editing Data From a Domain Service
    • Walkthrough: Displaying Data in a Silverlight Business Application
    • Walkthrough: Displaying Related Data in a Silverlight Business Application
Powered by GitBook
On this page
  • Data Relationships
  • Data Annotations and Validation
  • Data Concurrency
  • Transactions
  • See Also
  • Concepts

Was this helpful?

  1. Middle Tier

Data

PreviousHow to: Use HTTPS with a Domain ServiceNextCompositional Hierarchies

Last updated 4 years ago

Was this helpful?

[ This document was written for WCF Services Version 1 Service Pack 2 and might not be up to date Please see or for a list of changes since WCF RIA Services ]

This section describes how Open Ria Services deals with scenarios involving modeling data, checking the validity of the data, and ensuring data concurrency. When you provide an interface for updating, deleting, or creating data from the client of a Rich Internet Application (RIA), you frequently need to model some complicated data relationships, and ensure that the data from the user is valid and still current with data in the data source before committing the data changes.

Typically, you use the Entity Data Model or LINQ to SQL to model data that exists in a relational database. However, you are not required to use a database in a Open Ria Services project. You can use any type of object to store data. The code in the client project that facilitates data operations is data source agnostic in the sense that it is actually unaware of the data access technology or of schema used by the middle tier.

Data Relationships

Open Ria Services provides features that enable you to interact with complicated data relationships, such as, hierarchical models, polymorphic inheritance models, presentation models that consolidate values from many entities, and models that include values from more than one domain service. The hierarchical model represents a parent and child composite relationship, such as Order and OrderDetails, or a recursive relationship, such as an Employee model that includes a field for a ManagerID that points to another entity in the Employee model. For more information, see .

In an inheritance model, you can represent a data structure that includes a Customer entity and two entities that derive from it: PublicSectorCustomer and PrivateSectorCustomer. Using domain operations, you can query and update the types. For more information, see .

Support for non-entity complex types has been added in Open Ria Services V1.0 SP1. Specifically, support is provided for codegen, metadata, deep validation, change tracking, edit sessions and complex type parameters. This means that custom types, such as Address, can now be used as entity properties or parameters or return values from methods. For more information, see the topics.

Support for sharing an entity with multiple domain services has been added in Open Ria Services V1.0 SP1. This enables the flexibility needed to segment your classes more logically. For more information, see the topic.

In a presentation model, you can build types for the presentation tier that are not tied directly to the structure of the data source tables. For example, you can build a data type named CustomerPresentation that is based on data classes for Customer, CustomerAddress, and Address tables. In the presentation type, you aggregate only the values that are relevant to the presentation tier. If changes are made in the data repository, you can change only the presentation type and not update the code client application that interacts with the data. Open Ria Services enables you to update data through the presentation type. For more information, see .

Finally, in your application, you may need to display data from a variety of data sources or expose a single entity to more than one domain service. Open Ria Services enables this scenario by supporting references between entities from different types. For example, an e-commerce Web site may need to integrate data from its order processing system with products from a third-party domain service. For more information, see .

Data Annotations and Validation

When you use data classes in your Open Ria Services application, you can apply attributes to the class or members that specify validation rules, specify how the data is displayed, and set relationships between entity classes. The namespace contains the classes that are used as data attributes. By applying these attributes on the data class or member, you centralize the data definition and you do not have to re-apply the same rules in multiple locations. The data annotation attributes are organized into three categories: validation attributes, display attributes, and data modeling attributes. For more information, see and . For validation, you can use the following attributes:

  1. DataTypeAttribute

  2. RangeAttribute

  3. RegularExpressionAttribute

  4. RequiredAttribute

  5. StringLengthAttribute

  6. CustomValidationAttribute

<MetadataTypeAttribute(GetType(Address.AddressMetadata))>  _
Partial Public Class Address

    Friend NotInheritable Class AddressMetadata

        'Metadata classes are not meant to be instantiated.
        Private Sub New()
            MyBase.New
        End Sub

        Public AddressID As Integer

        <Required()> _
        <StringLength(60)> _
        Public AddressLine1 As String

        Public AddressLine2 As String

        <Required()> _
        <StringLength(30)> _
        Public City As String

        Public CountryRegion As String

        Public CustomerAddresses As EntityCollection(Of CustomerAddress)

        Public ModifiedDate As DateTime

        <Required()> _
        Public PostalCode As String

        <Exclude()> _
        Public rowguid As Guid

        Public StateProvince As String
    End Class
End Class
[MetadataTypeAttribute(typeof(Address.AddressMetadata))]
public partial class Address
{

    internal sealed class AddressMetadata
    {
        // Metadata classes are not meant to be instantiated.
        private AddressMetadata()
        {
        }

        public int AddressID;

        [Required]
        [StringLength(60)]
        public string AddressLine1;

        public string AddressLine2;

        [Required]
        [StringLength(30)]
        public string City;

        public string CountryRegion;

        public EntityCollection<CustomerAddress> CustomerAddresses;

        public DateTime ModifiedDate;

        [Required]
        public string PostalCode;

        [Exclude]
        public Guid rowguid;

        public string StateProvince;
    }
}

You return the result of a validation check by creating an instance of the ValidationResult class.

The following example shows a customized validation class that returns the results through an instance of the ValidationResult class.

Imports System
Imports System.ComponentModel.DataAnnotations

Public Module GenderValidator
    Public Function IsGenderValid(ByVal gender As String, ByVal context As ValidationContext) As ValidationResult
        If gender = "M" OrElse gender = "m" OrElse gender = "F" OrElse gender = "f" Then
            Return ValidationResult.Success
        Else
            Return New ValidationResult("The Gender field only has two valid values 'M'/'F'", New String() {"Gender"})
        End If
    End Function
End Module
using System;
using System.ComponentModel.DataAnnotations;

namespace HRApp.Web
{
    public static class GenderValidator
    {
        public static ValidationResult IsGenderValid(string gender, ValidationContext context)
        {
            if (gender == "M" || gender == "m" || gender == "F" || gender == "f")
            {
                return ValidationResult.Success;
            }
            else
            {
                return new ValidationResult("The Gender field only has two valid values 'M'/'F'", new string[] { "Gender" });
            }
        }
    }
}

Data Concurrency

Open Ria Services supports optimistic concurrency to insure data consistency and relies on developers to provide the logic for handling potential conflicts that can occur when updating a data source. When you enable users to update or delete data, you should make sure that the data in the data source has not been changed by another process

Transactions

See Also

Concepts

When working with data classes that are automatically generated, such as an Entity Data Model or LINQ to SQL classes, you do not apply the attributes directly to the generated classes because the attributes will be lost the next time the class is re-generated. Instead, you create a metadata class for the data class, and apply the attributes to the metadata class. A metadata class is a partial class that is designated from the data class as the metadata type. For more information, see .

The following example shows a metadata class with , , , and attributes applied to some of the properties.

You can create a customized validation attribute by adding a shared code file and in that file creating a class that implements the validation logic. When you define the customized validation class, you must provide at least some code other than auto-implemented properties for the class to be correctly generated in the client project. For an example, see .

The class implements the INotifyDataErrorInfo interface. This interface defines members that provide synchronous and asynchronous validation support. With the INotifyDataErrorInfo interface, validation errors are communicated to the client project without raising an exception. For more information about INotifyDataErrorInfo, see .

By default, Open Ria Services does not pass the entire original entity, along with the changed values, to the data access layer to check for data concurrency. Instead, Open Ria Services stores and passes back only those members that are marked with the attribute. This implementation enables you to optimize the performance of your application by specifying only those members that you want to participate in the concurrency check.

The behavior is implemented by applying the attribute to properties in a metadata class, or to the metadata class itself, or to the metadata classes themselves, when working with the Entity Framework. They can also be applied directly to properties or classes of CLR types when working with POCO-defined data models. For more information, see .

The Open Ria Services framework does not automatically create transactions, but you can add explicit transactions when submitting changes. To create your own explicit transaction, you override the method. For more information, see .

Release Notes
Changelog
Compositional Hierarchies
Inheritance in Data Models
DomainService
Complex Types
DomainService
Shared Entities
Presentation Models
DomainContext
Walkthrough: Sharing Entities between Multiple Domain Services
System.ComponentModel.DataAnnotations
Using Data Annotations to Customize Data Classes
How to: Validate Data
How to: Add Metadata Classes
RoundtripOriginalAttribute
RequiredAttribute
StringLengthAttribute
ExcludeAttribute
How to: Validate Data
Entity
INotifyDataErrorInfo Interface
RoundtripOriginalAttribute
How to: Add Metadata Classes
Submit
How to: Add Explicit Transactions to a Domain Service
Building Secure Applications with Open Ria Services