EntityFramework 4, code first and RIA Services

I was looking at EF4 and code first CTP5 and wanted to see how that works with RIA Services. So I took John Papa’s sample from PDC10 and started converting that to use code first.

Here are the steps

1.Becasue we already have a database and want to generate the classes quickly Open the EDMX file  right click and add code generation item and select “ADO.NET DbContext Generator” . this will generate the model classes and the context

2.After the classes are generated we will have a BookClubEntities class. we have to change the connectingstring to go directly to database

the modified connection string in Web.Config looks like this

<add name=”BookClubEntities” connectionString=”Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\BookClub.mdf;Integrated Security=True;User Instance=True;MultipleActiveResultSets=True” providerName=”System.Data.SqlClient” />

3. we need to override OnModelCreating to add our mapping. All of them are starightforward except for ImageSource column in the Book class. We dont have that in the Database, so we ignore it. Here is the context class after mapping

public partial class BookClubEntities : DbContext
{
public BookClubEntities()
: base(“name=BookClubEntities”)
{

}

public DbSet<BookOfDay> BookOfDays { get; set; }
public DbSet<Book> Books { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Checkout> Checkouts { get; set; }
public DbSet<Member> Members { get; set; }
public DbSet<Request> Requests { get; set; }

protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

//books
modelBuilder.Entity<Book>().Ignore(x => x.ImageSource);
modelBuilder.Entity<Book>().HasMany(x => x.BookOfDays).WithRequired(x => x.Book).HasForeignKey(x => x.BookID);
modelBuilder.Entity<Book>().HasMany(x => x.Checkouts).WithRequired(x => x.Book).HasForeignKey(x => x.BookID);
modelBuilder.Entity<Book>().HasMany(x => x.Requests).WithRequired(x => x.Book).HasForeignKey(x => x.BookID);

modelBuilder.Entity<Category>().HasMany(x => x.Books).WithRequired(x => x.Category).HasForeignKey(x => x.CategoryID);

modelBuilder.Entity<Member>().HasMany(x => x.Books).WithRequired(x => x.Member).HasForeignKey(x => x.MemberID);
modelBuilder.Entity<Member>().HasMany(x => x.Checkouts).WithRequired(x => x.Member).HasForeignKey(x => x.MemberID);
modelBuilder.Entity<Member>().HasMany(x => x.Requests).WithRequired(x => x.Member).HasForeignKey(x => x.MemberID);

modelBuilder.Entity<Checkout>().HasMany(x => x.Requests).WithRequired(x => x.Checkout).HasForeignKey(x => x.CheckoutID);

}
}

3. We have to map the classes to Tables, whereever the tablename differs from the class name we add “Table” attribute on the class for mapping and add “Key” attributes on the primary columns

4. We add Association Attribute on  all the properties that we want to include in our results.

5. Add the DbContextExtensions file. it contains useful extension methods. (I got the code from the EF forums posted by a user and refined by person from MSFT)

6. Last but not least change the code in the actual service to inherit from DomainService and modify the queries to go against the context we created and not ObjectContext

If all the mappings are right, we should have the application working again without the edmx file.

You can download the files changed or added here. This zip file has only the relevant files, not the whole application.

Advertisements