There's lots of cool pieces that are packaged up with WebMatrix initially, but these pieces are interesting for pro developers as well.

Still, something's missing.

In my mind, it's been too hard to talk to databases. I like LINQ to SQL and used it on the first NerdDinner version, but since EF4 sucks so much less is way better than earlier versions of EF, Jon and I updated NerdDinner to use EF. It was easy, but I would have liked to code first, and code only if I could.

Microsoft announced a new Entity Framework CTP today. It has the romantic and wonderful name "Microsoft ADO.NET Entity Framework Feature CTP4" which is lame. You can say "EF Feature CTP4" but I like "EF Magic Unicorn Edition" but that's just me. We're getting the tech better at Microsoft but still can't get naming right. Whadayagonnado? Still, it makes EF a pleasure.

It's got a lot of interesting features and choices, and while it's still a CTP, you should take a minute and check it out.

Quick CRUD via a Code First Model

After you install it (it won't mess up your system if you do), go and create a new whatever project. For my little example, I'll make a new ASP.NET MVC Website. It works for me better than a console app to illustrate a point.

Add a reference to Microsoft.Data.Entity.CTP.dll.

Make a new class, maybe in the Models folder, and name it something like Book. Add some code like this. Notice it's just code. Nothing derives from anything.

So that's a nice simple controller that uses a model that was written in just code. The database and its schema was created for me. The DbContext is LINQable with stuff like Add, Find, and Remove all just there. Plus, it's all EF under the hood, so if you need more complex stuff, you can do it.

For example, here's a more complex Code First Model with Collections, and more attributes. I show some fluent wiring up of relationships later on, although there are conventions that can assign bi-directionality based on naming.

Also, "Magic Unicorn EF" supports DataAnnotations (or validation via Fluent interfaces), so those [Required] and [StringLength] stuff from before? Those apply not only in JavaScript, but also at the Server-side and Database persistence layers.

You can make your own strategies for creating databases, based on what's going on with the model, if it's changed, etc. Here's some built-in examples. Yours can do whatever you like. Here the SimpleBookCatalog is the DbContext from before.

//This is the default strategy. It creates the DB only if it doesn't existDatabase.SetInitializer(new CreateDatabaseOnlyIfNotExists<SimpleBookCatalog>());//Recreates the DB if the model changes but doesn't insert seed data.Database.SetInitializer(new RecreateDatabaseIfModelChanges<SimpleBookCatalog>());//Strategy for always recreating the DB every time the app is run.Database.SetInitializer(new AlwaysRecreateDatabase<SimpleBookCatalog>());

Connection Strings for the SQL 4 CE provider are simpler (like, they are possible to memorize, which is amazing, considering how hard they are now). For example:

Here's some examples of fluent mappings and setting up relationships to give you an idea of the kinds of things you can do, while avoiding looking at any visual designers. It all depends on how clean you need your POCO (Plain Old CLR Objects) to be.

These configurations can be batched up into a class that handles configuration for a specific entity so you can reuse them and more easily config like this.

builder.Configurations.Add(new BookConfiguration());

All this is a really basic example as a means of introduction and for my own learning, but so far I like it. It takes just a few minutes to get a lot done without much code. Since this is all Entity Framework, I can put an OData service on top of my model really quickly and then start consuming those services from iPhones or whatever.

It'll be interesting to take a sample like Nerd Dinner or MVC Music Store and change them to use Code First EF and the Razor View Engine and see if they are more readable and how many fewer lines of code they are.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

I really like the idea of code-first, but I have two reservations/thoughts:

1) How do you manage important physical properties of the database like indexes? From what I see these would have to be managed outside the scope of the code-first specification. Yes I know some people will say that physical database design should be left up to the DBAs, but I think its not so clear cut these days. In fact I believe that sensible indexes can and should be designed a priori. I guess different persistence platforms may need different configurations physical designs as well.

2) This all starts to get into the area of "modelling" as in what they are trying to solve with SQL Server Modelling. If you define your model with c# as opposed to something higher level or more generic (e.g. "m") then are you restricting how easily you can repurpose that model? I can see this code-first+data annotations being an awesome end-to-end solutions to get something build quick and keep you brain focused on business value not keeping all the layers synchronized. But in some ways as soon as you want to step outside this scenario you will wish you had a model (or a variant of it ) that can be more easily reused. Perhaps even outside my app? I guess it is not very lean of me to consider such complications when this stuff can probably solve 90% of my requirements! So... is this all a precursor to SQL Server Modelling? I'm not sure but I suspect we are seeing a specialization of what they are trying to generalise with "m".

I used the previous CTP and really liked the Code first approach. There are extended methods that allow you to persist the edmx (this really just creates a runtime edmx), so it would be a decent workflow to start with code, then move to the model as the thing. I think it all points to SQL Server Modelling in the future, but my sense is that we are not yet there.There are still some rough patches in EF 4, for me the biggest being simple support for System.Enum code types, but it is really promising.

robert schroeder

Thursday, 15 July 2010 08:35:35 UTC

It almost seems like a natural extension to EF, what with already being able to model data as entities why not allow the entities themselves define the structure of the underlying data store.

Jack's comment around physical properties of a DB is an interesting one, but presumably this is either a) implementation-specific and as such not something you'd necessarily concern yourself with when merely creating as data store with entity markup, or b) something that is actually supported by the Magic Unicorn feature and we've just not seen it yet.

Very interesting stuff and something I look forward to playing around with shortly.

In fact, to follow up on Jack's query regarding physical features and my previous comment, it appears to be answered on the ADO.NET blog article:

"In CTP4 we have implemented the following conventions:o Primary Keyo Relationship Inverseo Foreign Keyo Pluralization of Table Nameso Support for Data Annotations

We posted details about all the Data Annotations we plan to support here The annotations supported in CTP4 are:o Keyo StringLengtho ConcurrencyChecko Requiredo Timestampo DataMembero RelatedToo MaxLengtho StoreGenerated"...

This is great!Now please help them get IoC built into ASP.Net MVC (it's a pit of success thing) and work out a solution for managing interacting and overlapping models in our applications.If this results in the option to do MEF-based CQRS, that would be "tha bomb", but hey, I'll settle for less to start with :-)

1. Re: where is the injection point to specify physical database artifacts like indexes>> This is something you can do with CTP4. We'll be posting some follow-up blog posts on the ADO.NET team blog in the next week about how to customize database initialization, seed it with sample data, or do all kinds of extra goodies.

2. Re: CodeFirst's relationship with SSMoS and model re-usability>> This is coming, but it's going to take a bit longer. We're working on defining our experience of using Code First with various kinds of tooling/designers as optional workflows. So if you don't want to go 100% code, you'll have some alternatives you can augment your app with while still being primarily code focused.

Oh, and EF + Enums. Yeah, we know. It's coming :)

Jeff

Jeff

Thursday, 15 July 2010 16:51:11 UTC

This is all cool, but obvious features. Why is it that it takes the EF Team forever to ship it?

This is a bit of an aside - in the intro you say (boldfaced for emphasis):

"Razor" Page Syntax - A way to make pages/ViewEngine called "Razor." Your sites can be later be expanded to use all of ASP.NET MVC. It's a simple syntax that is easy to learn.

When I first read this it looked like you were suggesting Razor is not a full-fledged view engine, as capable as the current view engine. I had to comb through ScottGu's article until the VERY end, where he stated in the summary that: <blockquote cite=ScottGu">You can also drop standalone .cshtml/.vbhtml files into your application and run them as single-pages – which also enables you to take advantage of it within ASP.NET Web Forms applications as well.</blockquote>

This asp/php style of programming available through Razor ought to be highlighted a bit more.

This is everything that I had been wishing for this Christmas I just hope that I can get a RTM version before then. This is starting to be SubSonic cool but hopefully with a bit fewer bugs... So where do I go to add feature Requests?? There is just one more thing I would like to add.... If I create properties in my classes named CreatedBy/CreatedOn/ModifiedBy/ModifiedOn I want EF10 (I know you like EF Magic Unicorn but I like the idea of it skipping a lot of version numbers as it did have a lot of kinks to get worked out) to know what to do with those columns namely grab a UserName out of thin air like SubSonic does and update the Dates each time it gets saved without making me write those four lines over and over again. I can't wait to give it a try as this is what I thought it did when I first heard about Code First in EF4.

The whole disposable aspect of the entity framework is its greatest downfall. It seems like a small thing, but I don't think entity frameworks should create disposable. I realize the actual database classes (such as SqlConnection) are disposable, and I think okay. But frameworks designed to exist up the stack shouldn't require anything that ties your hands such as IDisposable.

The ASP.NET MVC examples use an instance of the entity framework without disposing (such as the music store example).

I noticed that you mentioned that it "sucked less". EF4 doesn't suck that bad. It can be made to work. I have a basic ActiveRecord pattern being generated by T4 templates sitting on top of a very simple repository. This creates workable code that doesn't suck to work with, but it could be so much better.

The entity framework has a few fundamental problems that hopefully can be solved in future releases.

1. Disposing should not be in this framework.

2. No particular pattern. EF4 tried to be the lowest common denominator, instead of picking a particular pattern for data access it leaves that up to the user. While that is the most flexible, I believe constraints are more liberating. If EF4 forced people down a simple pattern it would be more useful and suck less.

3. Working on multiple results set at a single time can create strange exceptions. If you follow a rigid pattern when using EF4 this can be avoided, but otherwise...

scott,hope ms can finalize this ASAP, im a hardcore, linq to sql fan, dont like the current EF, tried (DONT LIKE IT) still love linetoSQL, altho its does a horrible job with (inner joins and sub query), my solution, well just use SP for complex queries.

but this looks very promising, as long as its

EASIER, & BETTER!

im willing...

just that i cant work with CTP, what if the final version has revision, dont have the time to re-code for LIVE system. loooking forward to final version.. what is that????

I keep hearing arguments for repurposing, and how code first restricts the model, but seriously just HOW many times has anyone 'repurposed' a data layer. its the same argument for "writing a layer so we can swap out xxxx if we need to.". Simple truth is that 99.9% of the time , you'll never swap out your data layer or any other layer. If you're going to make the change from SQLServer to Oracle, or anything to anything, its usually best to worry about that when it happens.I've been around quite a number of years, and i've *never* come across a project where we'd write stuff so we could 'repurpose' what we'd already got.

However, I'd love to see non theoretical, non trivial samples too. Just in case I'm wrong. Which I probably am.Good work Scott. Keep it up.

How can you specify your own database if all you want to do is map to one, and not have it generate one? This is really frustrating because you keep showing how it can make its own, but because of how long most of us have had to keep waiting on code-first, we've had to go ahead and make systems that use the old UI designer model with existing databases.

You reference a map to ProductContext; What is ProductContext? Where is it created? Is it an ObjectContext or a DbContext? What kind of parameter are we needing so that it can accept a specified database? Etc. Etc. It'd be really nice if some of these kinds of things could be clarified.

Thanks for the information. I'm looking forward to see how Code'First' develops. I think that's a misnomer, though. I haven't spoken to a programmer yet that cared about making their database with code, just mapping to it.

Derek

Friday, 16 July 2010 16:48:15 UTC

Derek,I want the database to be scripted from the model really, and code is a great way to start building the model via conventions. IMHO, T-SQL is a horrible language for database and table creation and modification. M looks to be a huge improvement and when that gets tied to EDMX, I think we will have a great way to 1) provide standard classes of functionality that can evolve (I will have many tables that always are tied to a tenant id, and always have standard columns, others that do not, but fall into a different pattern (say M2M relationships), etc.) If I can model that at the conceptual level, then I can evolve my database at the appropriate level of abstraction. Ultimately, the model should be the key, again, IMO, because it is the thing that should know about both the store and the code, and the model should be rich enough to encompass all patterns, but simple enough to make the common things easy and the unusual possible. End soap box.

robert schroeder

Friday, 16 July 2010 17:09:44 UTC

Derek, sorry if this post was too much of a summary. There's a LOT here and I could have dug and dug deeper. ProductContext in my little snippet was a DbContext. I'll change a few names in the post to try to make it more cohesive for future readers.

Random Google Open ID Guy - Yes, that was my mistake. ISBN should be an int. I changed it above.

Rob - Totally get you. You can pass in a regular Connection String to a DbContext derived class and, if you like, use CodeFirst (perhaps manually, perhaps via code generation) to describe an existing database.

@Derek For a bunch of people the database is just an artifact, somewhere to store the data. Many projects start that way too.

If you already have an existing database why would you want to represent it in code? There are already great tools that will generate the mapping EDMX file from a database and let you visually tweak it if needed.

If I am using something like StuctureMap or Unity with MVC, I wonder what the best way would be to inject SimpleBookCatalog into the controller? Would it be to simply just extract an interface from it and inject ISimpleBookCatalog into the controller's constructor, or should I do something like nHibernate where you configure the session on the application start up?

This is a good walkthrough, enough detail to see that the featureset of NHibernate + FluentnHibernate Automap is close to at parity. I would say my use of nhibernates days are now numbered. It seemed like it was just a matter of time and I am glad to see the teams that are farther down the stack helping build in the features that the smaller but loud community really digs. Good to see this coming together.

I've long had the concerns expressed so well by @Jack near the top of the comments. It's good/interesting to see from a later comment that these are/will be covered by the MMU team (I can't type that name in full!)

I wonder how this plays along with depdency injection and n-tier applications. When you say "Entity Framework quietly slips into the background" will the dbcontext invade my top tiers? Will I still be able to cleanly separate the layers?

Florian Hötzinger

Wednesday, 21 July 2010 09:33:55 UTC

Edit: You didnt actually say "Entity Framework quietly slips into the background" , Julie Lerman did and I copied my comment from there ;)

Florian Hötzinger

Wednesday, 21 July 2010 12:11:46 UTC

Florian, wrt - "the dbcontext invade my top tiers? Will I still be able to cleanly separate the layers?"

As presently defaulted it is certainly possible for the dbcontext to infiltrate, but you can with work, knowledge and vigilance, cleanly separate the layers. I would not classify that as a pit of success default though.It seems to me to be defaulting, at present, to getting something up and running for a very quick demo rather than defaulting to something that is truly architecturally sound. There has been a lot of progress on the different code generation templates, and a lot to like in the flexibility, but it is hard to get your head around what features require what when you start writing custom templates, at least in my own limited experience.

robert schroeder

Wednesday, 21 July 2010 18:11:20 UTC

So I was wondering, does the CTP work with the Compact 4 ?

4. Code first programming model support for Compact 4.0 in ADO.NET Entity Framework: The Microsoft ADO.NET Entity Framework Feature Community Technology Preview 3 is an early preview of the code-first programming model for the ADO.NET Entity Framework 4.0. The code-first feature in the ADO.NET Entity Framework CTP3 release does not work properly with Compact 4.0. Future releases of code-first programming model for ADO.NET Entity Framework will provide support for code-first programming model for Compact 4.0.

How would you do an update to an entity using the repository pattern? Adding a new entity is still a simple call to myRepository.dbContext.Books.Add(newBook), but updating an existing one seems to involve finding the original object from the dbContext, manually changing each of the updated properties and then calling SaveChanges on the dbContext again. It seems like the framework could handle this better, much like a simple call to UpdateModel(book) in the controller.

Benjamin Rice

Friday, 23 July 2010 05:59:24 UTC

This is great stuff but I have hit a road block that I can't figure out. I am trying to use this with a SQL 2008 db & using a data context that implements ObjectContext like so:

public class DataContext : ObjectContext

And then in my constructor I am passing a named connection string to the base like so:

Code First actually calls the EF Provider it's currently working with to figure out correct storage types so it should work with Oracle providing you have an Oracle provider with full ADO.NET 4.0 support.

Is there a way to hook class-level validation into these objects? Let's say I wanted to look up the "First Published" date for a book and make sure that the Author was still alive then, or something like that where I've got to examine multiple fields on the object. I haven't seen an overridable method or anything like that -- any ideas?

I am not sure which CTP4 version you are looking at but I am not able to find any RelatedTo attribute with named properties described in the ADO.NET blog or here. Moreover, the HasOptional or HasRequired does not work in the manner described here. For instance:

Now with the configuration on DefinedObject with HasRequired(t => t.DefinedType).WithMany(o => o.DefinedObjects) the EF tries to query DefinedType_Typename on DefinedObject why??

Is this a bug or is there a version which we don't know about?

Thanks,PG

PG

Friday, 06 August 2010 21:39:41 UTC

Is it possible to have a single Model bound to a dynamic table name? For Instance, in our database you can create multiple tables "Managers", "Employees", "Accountants" - all dynamic. Using Linq we overrode the MetaModel.GetTable to add custom attributes based on a parameter passed to the DataContext initializer. However, we are unable to do that with EF yet or we just don't see how it's possible. Any insight would be helpful (on the same vein we'd like to use the DataContext to create a new table when necessary)

-Morder

Morder

Thursday, 12 August 2010 10:11:41 UTC

Good post , thanks

monolight

Tuesday, 24 August 2010 15:50:23 UTC

Hi Scott,

I have some trouble with modifying a 1-1 relationship. I use a one direction relationship: Product -> Brand. When I modify the brand by selecting another existing one, the DbContext.SaveChanges() method creates a new Brand with the same values of the exsiting Brand but with a new Id. How do I solve this problem?

I created a MVC2 View with EditorForModel() using the Product as model, which resulted in a textbox (ProductName property) and a DropDown listbox (Brand property). When I change the value of the dropdownlist, I use the ProductModelBinder.GetPropertyValue() method to retrieve the selected Brand from the BrandRepository using the Brand.BrandId value I received from the view. In the controller, I created the following Action:

// This works nice too, now Product.BrandId contains the BrandId of the selected Brand. // The Attach() method of this repository executes DbSet<Product>.Attach() and // DbContext.ObjectContext.ObjectStateManager.ChangeEntityState(product, EntityState.Modified) productRepository.Attach(entry);

// SaveChanges() goes wrong: now Product.Brand contains a NEW Brand with the // values of the selected one and with a new BrandId productRepository.SaveChanges();

Scott,would the Code First DbContext work as a WCF Data Service?I tried it, but got he following error :

The server encountered an error processing the request. The exception message is 'On data context type 'CustomerService', there is a top IQueryable property 'Customer' whose element type is not an entity type. Make sure that the IQueryable property is of entity type or specify the IgnoreProperties attribute on the data context type to ignore this property.'. See server logs for more details.

John

Friday, 17 September 2010 03:06:52 UTC

>would the Code First DbContext work as a WCF Data Service?>I tried it, but got he following error :

In CTP4, DbContext doesn't directly support exposing to DataService but here's a simple workaround:http://romiller.com/2010/07/19/ef-ctp4-tips-tricks-wcf-data-service-on-dbcontext/

ScottGu also had a blog entry on Code-First and modifying the underlying database mappings. In both of these posts, you two show how you can: 1) map a "complex property" into columns within the entity database table and 2) in your post specifically, how to use inheritance. What I'm wondering, though, is is it possible to split a POCO class's attributes into multiple database tables?

For example, in the ASP.NET membership system, there is no way to associate a user's first and last name with the Member object without doing one of two things: 1) Using the standard ASP.NET Profile provider or 2) creating your own MembershipProvider. What I would like to do is have a "super POCO object" that includes all information about a user (particularly first and last name, office number/location...it's not really "profile data", it's a part of who a member is in my project) and have those attributes be stored in two or more tables. This prevents, for instance, having to access these "properties" of member via Member.Profile.FirstName, or Member.User.UserName. Conceptually, it's easier if I could just write Membe.FirstName or Member.UserName, etc.

Great stuff - but I found one issue that you may already be aware of...

According to the EF Data Annotations setting the Required Attribute on a navigation reference property (ie a 1 to many relationship instead of a 0..1 to many).

I tried this in my model like so:

[Required] public virtual Person Person { get; set; }

but its generating the PersonID column as nullable and its not giving an exception when leaving this property null. However, I tried setting the HasRequired method in the model Builder and it DID work as expected.

modelBuilder.Entity<Inquiry>().HasRequired(b => b.Person);

So I'm guessing this might just be a feature that is not yet wired up in the beta. Or please feel free to let me know if I am just missing something.

Thanks Scott. Could you blog about a simple example of a one-to-many property that is implemented with a dropdown list? This seems like it would be a common problem, but I can't find an example.

Eric

Tuesday, 16 November 2010 22:25:52 UTC

Just to be clearer about my last post. If you wanted to add a Category to your book class, but you didn't need/want your category class to have a property that was a list of books in that category.

Eric

Thursday, 02 December 2010 23:15:01 UTC

Following your examples, I keep getting the "unable to infer a primary key" error on any of the tables I try to access. I am using the [Key] attribute as you indicated, but it seems to have no effect. I also tried declaring the key in OnModelCreating in the DbContext as you suggested. This at least gives me a different error: "Key expression is not valid." Has anyone else run into this? I'm using .NET 4, VisualStudio 2010, etc.

Josh Fuller

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.