Entity Framework 4.1 Code First (With One to Many relationship) Code Example


A quick piece of code demo’ing a very common/ simple usage scenario- basic one to many with some demo data being seeded into the database; I thought this might be needed as I’ve waded through a LOT of exmaples for various beta versions and different releases of EF, but had little luck actually finding something relevant. The best site I came across was tucked away on the ADO.net team’s blog- Using DbContext in EF 4.1. First– the entities and the database context

    public class Category
    {
        [Key]
        public Guid ID { get; set; }

        public string Title { get; set; }
        public virtual ICollection<Product> Products { get; set; }  
                   //virtual makes this lazily loaded

        public Category()
        {
            this.ID = Guid.NewGuid();
        }
    }

    public class Product
    {
        [Key]
        public Guid ID { get; set; }

        public string Title { get; set; }
        public string Details { get; set; }
        public double Price { get; set; }
        public string ImageFileName { get; set; }

        public DateTime DateAdded { get; set; }

        public virtual Category Category { get; set; }  
                   //virtual makes this lazily loaded

        public Product()
        {
            this.ID = Guid.NewGuid();
        }
    }

    public class MyDBContext: DbContext
    {
        public DbSet<Product> Products { get; set; }
        public DbSet<Category> Categories { get; set; }
    }

Note the use of ICollection on Products in Category, and the use of DbSet in the context. I used a DbSet in lieu of ICollection on the Products entity and found it went mental if I had a Product with no category (something which I wanted to be valid) – swapping it to ICollection fixed this issue (I don’t know enough of the inner workings to explain why)

BAMM! Next for the seeding- add a class like so;

    public class MyDBInitializer : DropCreateDatabaseAlways<MyDBContext>
    {
        protected override void Seed(Entities.ComicolleDB context)
        {
            Category marvel = new Category()
            {
                Title = "Category 1"
            };
            Category dc = new Category()
            {
                Title = "Category 2"
            };

            context.Categories.Add(marvel);
            context.Categories.Add(dc);

            context.Products.Add(new Product()
            {
                Title = "Test1",
                ImageFileName = "image-1.gif",
                Details = "This is a test",
                Price = 4.99,
                DateAdded = DateTime.Now,
                Category = marvel
            });

            context.Products.Add(new Product()
            {
                Title = "Test2",
                ImageFileName = "image-1.gif",
                Details = "This is a test",
                Price = 4.99,
                DateAdded = DateTime.Now,
                Category = dc
            });

            context.Products.Add(new Product()  // no category
            {
                Title = "Test3",
                ImageFileName = "image-1.gif",
                Details = "This is a test",
                Price = 4.99,
                DateAdded = DateTime.Now
            });

            context.SaveChanges();
        }
    }

Then add the following line to the end of your Application_Start() method in global.asax;

Database.SetInitializer<MyDBContext>(new MyDBInitializer());

Voila- you can then go ahead and use your model in whatever applications you see fit- here are some example;

MyDBContext db = new MyDBContext();

// get a category, and make sure the products are loaded
Category the_category = db.Categories.Include("Products")
                           .Where(x => x.Title == "Category 1").SingleOrDefault();

// get all the products for that category
List<Product> some_products = the_category.Products;

// get all the categories (without loading the products)
List<Category> some_categories = db.Categories.ToList();
  1. #1 by maz3tt on May 4, 2012 - 09:04

    great keep up the good work

(will not be published)