The short example about EF4 CTP4 using DataAnnotation configuration

In the last post at here, here and here, I wrote about EF4 (Entity Framework 4) with code-first approaching. In 3 parts, I used the configuration class for mapping with database (this feature is like Fluent NHibernate). But in the CTP4, we also use the DataAnnotation (new feature in .NET 4) for mapping with database. If we use the DataAnnotation, we shall be easy to mapping with much Convention over Configuration rules. You can go to this link for read all convention’s EF4 CTP. As Andrew suggest me, the example for mapping of my last post is very simple and did not have complex. So I downloaded the Northwind database from Microsoft and implemented in this post. Why do we use the DataAnnotation? As you know, Microsoft integrated it into .NET 4, and now they used it in all new technology, such as Silverlight, WPF, ASP.NET MVC… And in the future I think it will become popularly. And we shall be familiar with it, use it easily. In this post, I will explorer about mapping use the DataAnnotation, and some convention in relationship for ORM mapping.

To avoid you hard to understand, I will explain some basic convention that I used in this post.

A property is a primary key if the property is called ‘Id’ or ‘<class name>Id’Relationship Inverse should the same with this example: 
    public class Product
    {

        public int ProductId { getset; }

        public string Name { getset; }

        public Category Category { getset; }

    }
    public class Category
    {

        public int CategoryId { getset; }

        public string Name { getset; }

        public ICollection<ProductProducts { getset; }

    }
In [Product] entity, we have Category entity as the foreign key, so the [Category] field should be the same name with it. And in the [Category] entity, we have many products, so the collection of products should be having s after; it’s meaning the plural noun.  Ok that enough to do in this post, I shall start implement this post now.The first thing you can do is download enough tools to installing. At here, you need the EF4 CTP4, sample Northwind database. You can find in Google and download it, after installed it you are already to start.We need to build the database schema as below with the code-first approaching.  As you know, entity model is the heart of modern software today. So we must build the entity first (at here is POCO objects). Because the Northwind database has many tables, so I only show 3 entities as here for short introduce.

Product

    public class Product : IEntity
    {
        /// <summary>
        /// Gets or sets the product id.
        /// </summary>
        /// <value>The product id.</value>
        [Key]
        public int ProductId { getset; }

        /// <summary>
        /// Gets or sets the name of the product.
        /// </summary>
        /// <value>The name of the product.</value>
        [Required]
        [StringLength(40)]
        public string ProductName { getset; }

        /// <summary>
        /// Gets or sets the supplier.
        /// </summary>
        /// <value>The supplier.</value>
        public Supplier Supplier { getset; }

        /// <summary>
        /// Gets or sets the category.
        /// </summary>
        /// <value>The category.</value>
        public Category Category { getset; }

        /// <summary>
        /// Gets or sets the quantity per unit.
        /// </summary>
        /// <value>The quantity per unit.</value>
        [StringLength(20)]
        public string QuantityPerUnit { getset; }

        /// <summary>
        /// Gets or sets the unit price.
        /// </summary>
        /// <value>The unit price.</value>
        public double UnitPrice { getset; }

        /// <summary>
        /// Gets or sets the units in stock.
        /// </summary>
        /// <value>The units in stock.</value>
        public short UnitsInStock { getset; }

        /// <summary>
        /// Gets or sets the units on order.
        /// </summary>
        /// <value>The units on order.</value>
        public short UnitsOnOrder { getset; }

        /// <summary>
        /// Gets or sets the reorder level.
        /// </summary>
        /// <value>The reorder level.</value>
        public short ReorderLevel { getset; }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="Product"/> is discontinued.
        /// </summary>
        /// <value><c>true</c> if discontinued; otherwise, <c>false</c>.</value>
        [Required]
        public bool Discontinued { getset; }

        /// <summary>
        /// Gets or sets the order details.
        /// </summary>
        /// <value>The order details.</value>
        public ICollection<OrderDetailOrderDetails { getset; }

        /// <summary>
        /// Initializes a new instance of the <see cref="Product"/> class.
        /// </summary>
        public Product()
        {
            OrderDetails = new Collection<OrderDetail>();
        }
    }

OrderDetail

    public class OrderDetail : IEntity
    {
        /// <summary>
        /// Gets or sets the order detail id.
        /// </summary>
        /// <value>The order detail id.</value>
        [Key]
        public int OrderDetailId { getset; }

        /// <summary>
        /// Gets or sets the order.
        /// </summary>
        /// <value>The order.</value>
        public Order Order { getset; }

        /// <summary>
        /// Gets or sets the product.
        /// </summary>
        /// <value>The product.</value>
        public Product Product { getset; }

        /// <summary>
        /// Gets or sets the unit price.
        /// </summary>
        /// <value>The unit price.</value>
        [Required]
        public double UnitPrice { getset; }

        /// <summary>
        /// Gets or sets the quantity.
        /// </summary>
        /// <value>The quantity.</value>
        [Required]
        public short Quantity { getset; }

        /// <summary>
        /// Gets or sets the discount.
        /// </summary>
        /// <value>The discount.</value>
        [Required]
        public float Discount { getset; }

        /// <summary>
        /// Initializes a new instance of the <see cref="OrderDetail"/> class.
        /// </summary>
        public OrderDetail()
        {
        }
    }

Order

    public class Order : IEntity
    {
        /// <summary>
        /// Gets or sets the order id.
        /// </summary>
        /// <value>The order id.</value>
        [Key]
        public int OrderId { getset; }

        /// <summary>
        /// Gets or sets the customer.
        /// </summary>
        /// <value>The customer.</value>
        public Customer Customer { getset; }

        /// <summary>
        /// Gets or sets the employee.
        /// </summary>
        /// <value>The employee.</value>
        public Employee Employee { getset; }

        /// <summary>
        /// Gets or sets the order date.
        /// </summary>
        /// <value>The order date.</value>
        public DateTime OrderDate { getset; }

        /// <summary>
        /// Gets or sets the required date.
        /// </summary>
        /// <value>The required date.</value>
        public DateTime RequiredDate { getset; }

        /// <summary>
        /// Gets or sets the shipped date.
        /// </summary>
        /// <value>The shipped date.</value>
        public DateTime ShippedDate { getset; }

        /// <summary>
        /// Gets or sets the ship via.
        /// </summary>
        /// <value>The ship via.</value>
        public Shipper ShipVia { getset; }

        /// <summary>
        /// Gets or sets the freight.
        /// </summary>
        /// <value>The freight.</value>
        public double Freight { getset; }

        /// <summary>
        /// Gets or sets the name of the ship.
        /// </summary>
        /// <value>The name of the ship.</value>
        [StringLength(40)]
        public string ShipName { getset; }

        /// <summary>
        /// Gets or sets the ship address.
        /// </summary>
        /// <value>The ship address.</value>
        [StringLength(60)]
        public string ShipAddress { getset; }

        /// <summary>
        /// Gets or sets the ship city.
        /// </summary>
        /// <value>The ship city.</value>
        [StringLength(15)]
        public string ShipCity { getset; }

        /// <summary>
        /// Gets or sets the ship region.
        /// </summary>
        /// <value>The ship region.</value>
        [StringLength(15)]
        public string ShipRegion { getset; }

        /// <summary>
        /// Gets or sets the ship postal code.
        /// </summary>
        /// <value>The ship postal code.</value>
        [StringLength(10)]
        public string ShipPostalCode { getset; }

        /// <summary>
        /// Gets or sets the ship country.
        /// </summary>
        /// <value>The ship country.</value>
        [StringLength(15)]
        public string ShipCountry { getset; }

        /// <summary>
        /// Gets or sets the order details.
        /// </summary>
        /// <value>The order details.</value>
        public virtual ICollection<OrderDetailOrderDetails { getset; }

        /// <summary>
        /// Initializes a new instance of the <see cref="Order"/> class.
        /// </summary>
        public Order()
        {
            OrderDetails = new Collection<OrderDetail>();
        }
    }
And after finishing the code for entity model, you will have this class diagram  As same thing with the past post at here, we need building the Repository, UnitOfWork, DataBaseContext, DatabaseFatory. It’s same with the last post, so I cannot paste code again, you can reference in my blog for it.Because I configure for create new database if there are no database or changed database schema. So after run the unit testing, we have new database schema at here.  As you saw, the database schema is the same with the original Northwind database schema at the first section of this post.

I hope this post will help some people that like the DataAnnotation for configuration. I attached the completed solution at the end of this post. Enjoy your code and see you next times.

4 Comments

Comments have been disabled for this content.