entity framework code first not creating tables using VS 2012 - entity-framework

I have a MVC4 Web api project under visual studio 2012 for which I would like to create and manage database using EF 6.0.2 code first. Actually, the solution entails four projects, namely,
OnlineShop.Application (User interface)
OnlineShop.Model dedicated to POCO classes only
OnlineShop.Test for unit tests and
OnlineShop.Core having UnitOfWork, GenericRepository and
DatabaseContext classes
Each of the mentioned projects includes an app.config which holds Same connection as that of web.config.
Problem: After running the project (in debug mode), the database is created as it's shown on server explorer (in visual studio 2012). But, it has no tables!!!
The database context class is also as the following:
public class DatabaseContext : DbContext
{
public DatabaseContext() : base("OnlineShopDb")
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DatabaseContext, Configuration>());
}
//public static void InitializeDatabase()
//{
// using (var context = new DatabaseContext())
// {
// context.Database.CreateIfNotExists();
// Database.SetInitializer(new MigrateDatabaseToLatestVersion<DatabaseContext, Configuration>());
// }
//}
public DbSet<Person> Persons { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<Audit> Audits { get; set; }
public DbSet<RoleGroup> RoleGroups { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<UserInRole> UserInRoles { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<ProductCategory> ProductCategories { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Entity<Person>().Map<User>(c => c.Requires("Discriminator").HasValue("User"));
}
}
I have surfed the web so much, found lots of articles ans samples regarding EF code first approach but unfortunately couldn't handle this bad problem!
I would appreciate it if anyone could help me on this.

Entity Framework code first does not create your database until you try to access it, so run your project and try to get or insert some record to your database.
another usefull tip is that if you change your models EF by default will throw an exeption, and you will have to drop the current database so EF can crate a new one.
or I recomend you to change that default behavior this way

Related

Fetch data from multiple related tables using Entity Framework core and display in view in Asp.Net Core

I am working on one Asp.Net Core application using Entity Framework Core. That app is basically into E Commerce. I want to fetch information of particular product from multiple tables which are related to each other using the master table product, and then i want to pass the data to the View. Can anyone help me in this regard. I am unable to find any perfect solution of Joins and pass the related data to View.
To complete these steps you need Visual Studio 2022.
Based on current documentation:
public class OrderDetail
{
public int OrderDetailID { get; set; }
public int OrderID { get; set; }
public int ProductID { get; set; }
public int Quantity { get; set; }
public Order Order { get; set; }
}
public class Order
{
public int OrderID { get; set; }
public int CustomerID { get; set; }
public int EmployeeID { get; set; }
public DateTime OrderDate { get; set; }
public List<OrderDetail> OrderDetails { get; set; }
}
It is a very simple model which contains only two classes, Order and OrderDetail has a one-to-many relationship. The next step is to add a new context class and make sure to inherit from the DbContext class
public class MyContext : DbContext
{
public DbSet<OrderDetail> OrderDetails { get; set; }
public DbSet<Order> Orders { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(#"Data Source=(localdb)\ProjectsV13;Initial Catalog=StoreDB;");
}
}
Now to create a database using migrations from your model, install the following packages;
Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.Design
Once these packages are installed, run the following command in Package Manager Console.
Add-Migration Initial
This command scaffold a migration to create the initial set of tables for your model. When it is executed successfully, then run the following command.
Update-Database to apply the new migration to the database. This command creates the database before applying migrations.
If you need to learn how to set up relationships the following websites have very good documentation and walkthrough on the entity framework.
I hope the following links help:
https://entityframeworkcore.com
https://www.learnentityframeworkcore.com

Many to Many relationship in Asp.Net MVC 5 with Identity table and Custom table

I'm trying to make a relationship between the Users from the table generated by Asp.Net Identity with my own table. The relationship must be many to many, since many Users can work on the same Task (which is my table), and same time an User can work on multiple Tasks.
public class Task
{
public int ID { get; set; }
public string Name { get; set; }
public string UserID { get; set; }
public virtual ICollection<ApplicationUser> Users { get; set; }
}
public class ApplicationUser : IdentityUser
{
public int TaskID { get; set; }
public virtual ICollection<Task> Tasks{ get; set; }
// rest of the code
}
I try it this way but I get an error during migration (or run time)
"One or more validation errors were detected during model generation:"
Please help me solve this problem and archive what I need.
Try it like this:
public class Projects
{
public Projects()
{
ApplicationUser = new HashSet<ApplicationUser>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ApplicationUser> ApplicationUser { get; set; }
}
Application User
public class ApplicationUser : IdentityUser
{
public ApplicationUser()
{
Projects = new HashSet<Projects>();
}
public async Task GenerateUserIdentityAsync(UserManager manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
public virtual ICollection <Projects > Projects { get; set; }
}
Application Context :
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public virtual DbSet<Projects> Projects { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
now when I run this Mvc app and register, the db tables I get is like the following:
and the correct schema:
The things to be questioned are a lot, from my point of view important is to determine if you:
- can/should you mix application context and your model context ?
You can try it as shown below using Fluent API.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Task>()
.HasMany<ApplicationUser>(s => s.Users)
.WithMany(c => c.Tasks)
.Map(cs =>
{
cs.MapLeftKey("TaskRefId");
cs.MapRightKey("ApplicationUserRefId");
cs.ToTable("TaskApplicationUser");
});
}
Update : you can see this link too.
EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType
Error text is not related to your many-to-many relationship. It tips that other built-in entities are not configured properly. So, It would be nice if you provided full definition of your custom DbContext-class and how it is configured.
UPDATE
As i understood u are working with two different contexts. You must work with the same context, cause of u are extending IdentityContext, creating relationships and adding custom types. So problem then will be resolved itself.
Hope, this will help.

EF 6 - Invalid column name 'Discriminator', two DbContexts

I have an MVC 5 app. I would like to use the standard aspnet.identity provider to enable user login through the standard \Account views. However, I also need to connect to a third-party database and want to use EF code-first for this too.
The context for my main database I took from a Scott Allen Pluralsight. I don't know why or what the "ApplicationUser" class is doing inheriting from the IdentityUser but it worked in his video and with a previous website I created. It looks as follows:
namespace ESBAMPortal.DataLayer
{
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
}
class PortalContext : IdentityDbContext<ApplicationUser>, ESBAMPortal.DataLayer.IPortalContext
{
public PortalContext()
: base("ESBamPortalConString")
{
this.Configuration.LazyLoadingEnabled = false;
}
public virtual DbSet<DomainClasses.Portal> Portal {get; set;}
}
}
The context for the third-party database is as follows:
namespace ESBAMPortal.DataLayer
{
public class ESBContext : DbContext, ESBAMPortal.DataLayer.IESBContext
{
public ESBContext()
: base("ESBExceptionConString")
{
this.Configuration.LazyLoadingEnabled = false;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
public virtual DbSet<ActionType> ActionTypes { get; set; }
public virtual DbSet<Alert> Alerts { get; set; }
public virtual DbSet<AlertCondition> AlertConditions { get; set; }
public virtual DbSet<AlertEmail> AlertEmails { get; set; }
public virtual DbSet<AlertHistory> AlertHistories { get; set; }
public virtual DbSet<AlertSubscription> AlertSubscriptions { get; set; }
public virtual DbSet<AlertSubscriptionHistory> AlertSubscriptionHistories { get; set; }
public virtual DbSet<AuditLog> AuditLogs { get; set; }
public virtual DbSet<AuditLogMessageData> AuditLogMessageDatas { get; set; }
public virtual DbSet<Batch> Batches { get; set; }
public virtual DbSet<Configuration> Configurations { get; set; }
public virtual DbSet<ContextProperty> ContextProperties { get; set; }
public virtual DbSet<Fault> Faults { get; set; }
public virtual DbSet<Message> Messages { get; set; }
public virtual DbSet<MessageData> MessageDatas { get; set; }
public virtual DbSet<ProcessedFault> ProcessedFaults { get; set; }
public virtual DbSet<UserSetting> UserSettings { get; set; }
}
}
When I run the website I am able to pull data from the third-party website ok. However, when I try to login I receive the message:
Invalid column name 'Discriminator'
This is thrown as a result of making the call:
var user = await UserManager.FindAsync(model.UserName, model.Password);
Running EF Profiler I can see that it's attempting to execute the following SQL:
SELECT [Limit1].[C1] AS [C1],
[Limit1].[Id] AS [Id],
[Limit1].[UserName] AS [UserName],
[Limit1].[PasswordHash] AS [PasswordHash],
[Limit1].[SecurityStamp] AS [SecurityStamp]
FROM (SELECT TOP (1) [Extent1].[Id] AS [Id],
[Extent1].[UserName] AS [UserName],
[Extent1].[PasswordHash] AS [PasswordHash],
[Extent1].[SecurityStamp] AS [SecurityStamp],
'0X0X' AS [C1]
FROM [dbo].[AspNetUsers] AS [Extent1]
WHERE ([Extent1].[Discriminator] = N'ApplicationUser')
AND ((((UPPER([Extent1].[UserName])) = (UPPER('rob' /* #p__linq__0 */)))
AND (NOT ((UPPER([Extent1].[UserName]) IS NULL)
OR (UPPER('rob' /* #p__linq__0 */) IS NULL))))
OR ((UPPER([Extent1].[UserName]) IS NULL)
AND (UPPER('rob' /* #p__linq__0 */) IS NULL)))) AS [Limit1]
Problem is, the AspNetUsersTable has no discriminator column.
Could anyone please explain where I've gone wrong and how I should fix?
I went back to basics, created a new MVC 5 app then generated a db migrations by running the following from the package manager console:
enable-migrations
add-migration 'first
When I inspected the code that was generated I could see that it included a "Discriminator" column in the AspNetUsers table.
I went back to my "real" solution and compared, the 'first' migration code from my separate DataAccess project. This code didn't have a "Discriminator" column, I also noticed that it had additional columns such as "PhoneNumber" and "TwoFactorEnabled". This made me think that perhaps the MVC5 template was using a previous version of "Microsoft.AspNet.Identity.EntityFramework" - this turned out the be the case.
To resolve I went to the Manage Nuget Packages dialog of the MVC5 web app, uninstalled "Microsoft.AspNet.Identity.EntityFramework"(v1.0) then re-installed (v2.0). Subsequently when I ran login from the website it no tried to find a "discriminator" column and everything worked great.
I guess this has taught me a valuable lesson to pay more attention to the versions on Nuget packages that are used by VS Templates
because the ASP.NET MVC project has a "ApplicationUser" class that already overrides IdentityUser it adds the Discriminator column to the entity framework for you automatically.
Try to drop the data base and rerun. again.
Check this http://forums.asp.net/t/1970682.aspx?ASP+NET+Identity+V2+Discriminator+Column
This happen for me when i was adding two classes inherited from IdentityDbContext if so add Discriminator to AspNetRoles
AddColumn("dbo.AspNetRoles", "Discriminator", c => c.String(nullable: false, maxLength: 128));
Try to drop the data base and rerun. again
Check this question
1. http://forums.asp.net/t/1970682.aspx?ASP+NET+Identity+V2+Discriminator+Column.http://
Also check this blogs.msdn.com/b/webdev/archive/2013/10/16/customizing-profile-information-in-asp-net-identity-in-vs-2013-templates.aspx

How can Lazy Loaded entities be tested using a mock DbContext?

I am using the fake DbContext recommended by Microsoft for unit testing with EF5.
Everything is working fine, however I am using a "code first" approach, and some of the code under test is relying on lazy loading of related entities.
public partial class Entity
{
public int EntityId { get; set; }
public string EntityName { get; set; }
public virtual ICollection<EntityLifeCycle> EntityLifeCycles { get; set; }
public virtual EntityStatus PreviousStatus { get; set; }
public virtual EntityStatus CurrentStatus { get; set; }
}
Sample of usage:
if (entity.EntityLifeCycles.Count() > 0)
{
...
}
How can I modify my test code (and not the code being tested) to accommodate this?
Researched links for reference:
Testing With a Fake DbContext
Mocking your Entity Framework data context and testing it in .NET MVC

Entity Framework 5, Code First and Add-Migration Using a Second DbContext Not Working

I have a problem with "Add-Migration" instruction when the Table definition is in a new DbContext Class.
I created a new ASP.NET MVC 4 Application in Visual Studio 2012.
I ran the "Enable-Migrations", "Add-Migration mig1", "Update-Database". Everything was smooth.
Than, I added a new class inheriting the DbContext to the Models folder. I was hoping that "Add-Migration mig2" will notice the new table definition. But it does not.
Any ideas why?
namespace MvcApplication4.Models
{
public class CmsContext: DbContext
{
public CmsContext()
: base("DefaultConnection")
{
}
public DbSet<CustomItem> CustomItems { get; set; }
}
[Table("CustomItems")]
public class CustomItem
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int Ordinal { get; set; }
public String Title { get; set; }
public String Content { get; set; }
public String FilePath { get; set; }
}
}
Multi-tenancy is not supported in EF5 but is supported in EF6 where you can specify a context for which you want to enable migrations for like this:
Enable-Migrations -ContextTypeName {NameOfTheContextType}
See the migrations multi-tenancy feature spec on the Entity Framework codeplex site.