MVC 4 SimpleMembership - Doing it right the first time - asp.net

Folks,
I just started to design a new web project. From VS2012, I generated a new Internet website project. It comes with a database that is already laid out with a few tables. This is fine.
Now, I need to extend the database with a few new tables and update UserProfile with few new fields. However, as this is going to be a new database, I don't want to enable migration steps and add code-bloat that is not really needed.
Here is the workaround I found:
Extend UserProfile with new fields as you would want to.
Add new tables in AccountModels.cs. For example,
[Table("Items")]
public class Items {
...
}
For each new table, add a DbSet field to UsersContexts class in AccountModels.cs.
public class UserContext : DbContext {
...
public DbSet<Items> Items {get; set; }
}
Delete the original database file, create a new database file with the same name, and run the application.
Voila. The new database gets filled with all the tables.
Is this the right way to do it?
Although it works, I am not really sure about step 3. I figured somehow the framework needs to know that a new table needs to be created and essentially adding a new field to UserContext triggers the creation of the new table. Is this the approach right?
Thank you in advance for your help.
Regards,
Peter

By not using code first migrations, deleting the database manually is the best thing you can do. There is also the DropCreateDatabaseIfModelChanges initializer but be careful to never use it in a release version of your app.
I would also recommend to write the DbContext in a seperate cs file. When you use the fluent api to configure the EF relations (what i would do), it can get really big. Think about putting the DAL and your models in seperate projects when your solution gets bigger. Using multiple contexts for one db can also cause problems, so naming it SomeAppContext would be better.

Related

Using code-first approach,I don't have an edmx file. what's the alternative?

I'm fairly new to asp.net mvc, so please bear with me.
I want to implement a calendar functionality, and all the tutorials I've looked at use database-first approach and have the edmx file (Entity Data Model)
I'm using code first and what can I do regarding the code that references this edmx file? do I reference context instead?
example:
public JsonResult GetEvents()
{
//Here MyDatabaseEntities is our entity datacontext (see Step 4)
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
var v = dc.Events.OrderBy(a => a.StartAt).ToList();
return new JsonResult { Data = v, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
Sorry if this question is vague or not clear.
Thank you and I'd appreciate help!
In code first, you don't need an edmx file, because everything is in your own code. The basic building blocks are:
A class that inherits from DbContext. This will be equivalent to the MyDatabaseEntities class in your sample.
A set of entity classes. They basically just need to be plain classes with auto properties corresponding to your database columns. For built in conventions to work, you also need an ID, for instance an int property named Id
A set of properties on your DbContext class of type DbSet for every type T which is an entity you would like to query against. This is the Events property in your example.
In more advanced scenarios you customize the mappings beyond what the conventions can infer automatically. This can be done with attributes on your entity classes, or via a special set of APIs that can be called on your context at startup
Go to Sql server inside your database there is a folder Database Diagram, Right click New Database Diagram and explore it.

How to implement Repository pattern for for handling Data in Asp.Net Core Web API project without Adding multiple Dbset lines for multiple Tables

I am trying to implement repository pattern in one of my personal projects. I am doing it with Asp.Net Core Web Api using Code First Approach. I am a complete beginner in this. So I apologize in advance if my question seems ignorant.
My question is, for every table in my database, I have to add
public DbSet<tableName> TableName{ get; set; }
in my DbContext, which does not seem like the correct approach. I was wondering if there was a generic way of doing this. I tried having a base class and all of my other data models inherit from that class. But this just creates a table for the baseclass. I could not find an answer to this anywhere. Is this possible? I don't want to have to edit db context every time I create a new Table. If this is possible please kindly guide me or provide a link to any tutorials.
Thanks in advance.
Adding DbSet for every table is correct approach.
it's not to many code to add multiple lines of
public DbSet<ClassName> TableName { get; set; }
Your DbContext have to "know" every table which it has to create. You don't have any other way to inform dbContext what to create.

Identity 2.0: ApplicationUser extension using a database first approach

From a couple of articles I have found online
http://typecastexception.com/post/2013/10/27/Configuring-Db-Connection-and-Code-First-Migration-for-Identity-Accounts-in-ASPNET-MVC-5-and-Visual-Studio-2013.aspx
http://www.codeproject.com/Articles/790720/ASP-NET-Identity-Customizing-Users-and-Roles
I have seen it is very simple to extend the ApplicationUser class in MVC 5/Identity 2.0. It basically requires adding of property to that class and all dependent views/viewmodels etc to implement the new functionality. The only question I have remaining is due to the fact that these articles all give you examples in regards to a code first perspective. How would extending the Applicationser class work with a database first perspective?
Here is what I imagine.
1.) Change the connection string to your production database. (In my case SQL Azure)
2.) Create the tables that are normally automatically created by identity 2.0 in SQL Azure.
3.) Fill those tables with the default properties and types.
4.) Add custom properties to the AspNetUsers table. (E.G. City, Zip, etc)
5.) Add those properties to the actual ApplicationUser class
6.) Update dependent views, controllers, viewmodels etc.
Is there a more simple way in doing this?
No, there is no other way to extend ApplicationUser. Code-First is pretty much the same, only adding properties first, create migration, run migration, update your controllers/views.

ASP.NET MVC4 - Error When Customize Default Accounts Models & Controller

I am in the begining of making a simple website using ASP.NET MVC4 CodeFirst Approach. The web site is built around users who are able to register, make posts etc. The existing UserProfile class was modified for the accommodation other fields (ex: FirstName, LastName etc).
When I ran the website I got a similar error:
Invalid column name 'FirstName'.
Invalid column name 'LastName'.
Invalid column name 'Phone'.
I red that this is because the Database is not updated as the model is updated. So I set the following on the Application_Start() in Global.asax with the intention of droppnng the database always (at least until I get the hang of it).
protected void Application_Start()
{
Database.SetInitializer(new DropCreateDatabaseAlways<UsersContext>());
//Other default generated stuff below...
}
I also tryed the DropCreateDatabaseIfModelChanges, but both methods didn't drop the database.
Isn't this possible? Why is it? Am I doing some thing wrong?
I believe it would be possible to store the info in a different table and link it to this, but I prefer to keep it in one table.
Also is it a bad idea to add UserProfiles to the websites context (lets say: DatabaseContext (which has other entities like Posts, Comments etc) and change the AccountsController to use DatabaseContext instead of UsersContext?
Thanks in advance.
Have you run Enable-Migrations in the Package Manager Console? You should see a migration folder in your project, with a configuration.cs file, ensure you have enabled automatic migrations.
public Configuration(){
AutomaticMigrationsEnabled = true;
//if you drop columns - consider this carefully...
AutomaticMigrationDataLossAllowed = true;
}

ASP.NET EntityFramework 4 data context issues

I'm working on a site and there are two projects in the solution a business logic project and the website project. I understand that I want to keep the entity context out of the web project and only use the business objects the framework creates but I can't figure out how to save a modified object this way.
Let's say my entity model created this class:
public class Person //Person entity
{
Int32 Id {get;set;}
String Name {get;set;}
Address Address {get;set;} //Address entity
}
And I created this class to get a specific person:
public static class PersonController
{
public static Person GetById(int id)
{
using (Entities context = new Entities())
{
return context.Persons.FirstOrDefault(x => x.Id == id);
}
}
}
This allows me to get a person without a context by calling PersonController.GetById(1); and I can change the persons properties after I get them but I can't figure out how to save the modified information back to the database. Ideally I would like to partial class Person and add a .Save() method which would handle creating a context adding the person to it and saving the changes. But when I tried this a while ago there were all kinds of issues with it still being attached to the old context and even if I detatch it and attatch it to a new context it gets attached as EntityState.Unchanged, if I remember right, so when I call context.SaveChages() after attaching it nothing actually gets updated.
I guess I have two questions:
1) Am I going about this in a good way/is there a better way? If I'm doing this in a really terrible way I would appreciate some psudo-code to point me in the right direction; a link to a post explaining how to go about this type of thing would work just as well.
2) Can someone provide some psudo-code for a save method? The save method would also need to handle if an address was attached or removed.
There are many ways to handle Entity Framework as a persistence layer.
For one, it looks like you're not using pure POCOs. That is, you let EF generate the classes for your (in the EDMX.designer.cs file).
Nothing wrong with that, but it does inhibit a clean separation of concerns (especially when it comes to unit testing).
Have you considering implementing the Repository pattern to encapsulate your EF logic? This would be a good way to isolate the logic from your UI.
In terms of Save - this is where it gets difficult. You're right, most people use partial classes. Generally, you would have a base class which exposes a virtual "Save" method, which the partial classes can then override.
I personally don't like this pattern - i believe POCOs should not care about persistence, or the underlying infrastructure. Therefore I like to use pure POCOs (no code gen), Repository pattern and Unit of Work.
The Unit of Work handles the context opening/saving/closing for you.
This is how (my) Unit of Work does the magic. Consider this some code in your "Web" project:
var uOw = new UnitOfWork(); // this is class i created, implementing the UOW pattern
var person = repository.Find(10); // find's a "Person" entity (pure POCO), with id 10.
person.Name = "Scott";
uOw.Commit();
Or adding a new Person:
var uOw = new UnitOfWork();
var newPerson = new Person { Name = "Bob" };
repository.Add(newPerson);
uOw.Commit();
How nice is that? :)
Line 1 creates a new sql context for you.
Line 2 uses that same context to retrieve a single "Person" object, which is a hand-coded POCO (not generated by EF).
Line 3 changes the name of the Person (pure POCO setter).
Line 4 Saves the changes to the data context, and closes the context.
Now, there is a LOT more to these patterns than that, so I suggest you read up on these patterns to see if it suits you.
My repository is also implemented with Generics, so I can re-use this interface for all business entity persistence.
Also take a look at some of the other questions I have asked on Stack Overflow - and you can see how I've implemented these patterns.
Not sure if this is the "answer" you're looking for, but thought I'd give you some alternative options.

Resources