1.5. Move the Data Context to a Separate Assembly

Often web applications architecturally consist of more than just the user interface layer, or the ASP.NET web site project. Most Dynamic Data demonstrations guide developers to place the database models in the App_Code folder. This practice violates modern programming practices of "not mingling user interface code with application code."

The following exercise will remove the data context from the user interface layer into a class library. Placing the database models at this level allows the web site as well as a Web Service, client application, console application, or any other type of UI layer to harness the business logic in the data context.

Begin by adding a new project to the solution by right-clicking on the solution name and selecting Add New Project. Select a Class Library project and name the project Domain (see Figure 11).

Figure 11. Figure 11

After creating the project, you must add a reference to the System.ComponentModel.DataAnnotations assembly (see Figure 12).

Figure 12. Figure 12

Next, add a new LINQ to SQL file to the project, naming it DB.dbml. Drag the Contact table from the Server Explorer window into the LINQ to SQL designer the same way you did as shown in Figure 2.

Now add a new class to the project named DBMetaData.cs. Copy the contents of the DBMetaData.cs file from the web site App_Code folder down to the file in the new class library.

Be mindful of the new namespace now being applied to the class in the Domain layer. You may want to copy the using statements and the body of the metadata class separately.

The following is how your DBMetaData.cs file should now look in the Domain project:

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;

namespace Domain
{
    [MetadataType(typeof(ContactMetadata))]
    [DisplayColumn("LastName", "LastName")]
    public partial class Contact
    {
        private string _newEmail;

        partial void OnEmailChanging(string value)
        {
            this._newEmail = value;
        }

        partial void OnValidate(System.Data.Linq.ChangeAction action)

{
            if (action == System.Data.Linq.ChangeAction.Insert)
            {
                using (DBDataContext db = new DBDataContext())
                {
                    var email = from c in db.Contacts
                                where c.Email == this._newEmail
                                select c.Email;

                    if (email.Count() > 0)
                    {
                        throw new ValidationException("Email addresses must be unique.");
                    }
                }
            }
        }
    }

    public class ContactMetadata
    {
        [DisplayName("Email Address")]
        [Required]
        [RegularExpression(@"^w+@[a-zA-Z_]+?.[a-zA-Z]{2,3}$",
            ErrorMessage = "A valid email address is required.")]
        [StringLength(150,
            ErrorMessage = "Your email address is too long.")]
        [UIHint("Email")]
        public object Email { get; set; }

        //[UIHint("Url", null, "EnableTest", "false")]
        //public object Url { get; set; }

        [UIHint("Url")]
        public object Url { get; set; }

        [Range(10, 20, ErrorMessage = "Font size must be a value from 10 to 20.")]
        public object PreferredFontSize { get; set; }

        [DisplayFormat(DataFormatString = "{0:g}")]
        public object CreatedOn { get; set; }

        [ScaffoldColumn(false)]
        public object ConcurrencyID { get; set; }
    }

    [ScaffoldTable(false)]
    public partial class aspnet_Applications { }
}

Now that your model and metadata live in the Domain project, you may delete DB.dbml and DBMetaData.cs from the App_Code folder in the web site project.

Finally, you must update the web application to point to the new location of the model and metadata information. First, add a reference from the web project to the Domain class library. Next, open the Global.asax and locate the line of code that registers the data context. Update this line to prefix the data context class with the Domain namespace.

Your code should now look like this:

model.RegisterContext(typeof(Domain.DBDataContext), new ContextConfiguration() {
ScaffoldAllTables = true });

Now run the web site to verify that you maintain access to the database tables.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.106.7