New fields not added in the database Code first - asp.net-mvc-4

I was following this tutorial which is about moving the SimpleMembershipProvider to your own database with custom fields in the userprofile table. I've added some new fields in the code:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string Mobile { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Then I run the Add-Migration command. And it generates a ######.cs file that looks like this:
namespace MVC4SimpleMembershipCodeFirstSeedingEF5.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class test : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
}
The up() and Down() methods have an empty body. Somehow it's not detecting the new changes (added FirstName and LastName fields) i have made.
What am I missing here?
EDIT:
I added the same fields to another table i have created, and that table did get updated in the database.
This is what Add-Migration produced:
namespace MVC4SimpleMembershipCodeFirstSeedingEF5.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class test : DbMigration
{
public override void Up()
{
AddColumn("dbo.TestTabel", "FirstName", c => c.String());
AddColumn("dbo.TestTabel", "LastName", c => c.String());
}
public override void Down()
{
DropColumn("dbo.TestTabel", "LastName");
DropColumn("dbo.TestTabel", "FirstName");
}
}
}
So the problem has been narrowed down to the userprofile table. Whats so special about this table that it can't be altered?

Related

How to add more fields to ASP.NET Core Identity?

I am using .NET 5 - version 5.0.100-rc.1.20452.10 .
I customized table AspNetUsers success, by this way
using Microsoft.AspNetCore.Identity;
using System;
namespace shadow.Models
{
public class ApplicationUser : IdentityUser
{
public string Fullname { get; set; }
public string AliasName { get; set; }
public string SecondMobile { get; set; }
public string About { get; set; }
public string Avatar { get; set; }
public DateTime? Created { get; set; }
public DateTime? Modified { get; set; }
}
}
and
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using shadow.Models;
namespace shadow.Data
{
public partial class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
{
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public virtual DbSet<ApplicationUser> ApplicationUsers { get; set; }
I am looking for a similar solution with table AspNetRoles. I need add filed Description to table AspNetRoles, how to archive this? Please guide me how to make change in ApplicationDbContext.
My effort: I tried
using Microsoft.AspNetCore.Identity;
namespace shadow.Models
{
public class ApplicationRole : IdentityRole
{
public string Description { get; set; }
}
}
but error
I feel hard when decare ApplciationRole to ApplicationDbContext
As we can see in the sourcecode Microsoft.AspNetCore.Identity.EntityFrameworkCore does not have a class for IdentityDbContext<TUser, TRole>. It has classes IdentityDbContext<TUser> and IdentityDbContext<TUser, TRole, TKey>. Hence, as described in point 5 of documentation
If a custom ApplicationRole class is being used, update the class to inherit from IdentityRole. For example:
using System;
using Microsoft.AspNetCore.Identity;
public class ApplicationRole : IdentityRole<Guid>
{
public string Description { get; set; }
}
Update ApplicationDbContext to reference the custom ApplicationRole class. For example, the following class references a custom ApplicationUser and a custom ApplicationRole:
using System;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
public class ApplicationDbContext :
IdentityDbContext<ApplicationUser, ApplicationRole, Guid>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
Where the last parameter Guid above is the type of the primary key for users and roles, as described here

select - keyword not working with odata, automapper and efcore

I am trying to apply the odata query to my automapper - mappings at my efcore context. Everything works as expected until I use the $select query option.
When I try to use the select keyword in the request to my odata - controller, I get the exception:
SerializationException: 'SourceSourceInjectedQuery`2' cannot be serialized using the ODataMediaTypeFormatter.
I am using the UseAsDataSource - Extension method because it was recommended here on github.
This is my oDataController:
public class StudentsController : ODataController {
private readonly SchoolContext schoolContext;
public StudentsController(SchoolContext schoolContext) {
this.schoolContext = schoolContext;
}
[EnableQuery]
public IActionResult Get() {
return Ok(
schoolContext
.Students
.UseAsDataSource()
.For<StudentVM>()
);
}
}
This is my Entity for EFCore:
public class Student {
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public ICollection<Enrollment> Enrollments { get; set; }
}
And this is my mappingprofile for automapper:
public class StudentVM {
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
}
public class StudentProfile : Profile {
public StudentProfile() {
CreateMap<Student, StudentVM>();
}
}
Do I need some specific mapping to do this?
I figured out I had a mistake in my configuration of the odataservice inside my startup.cs
private static IEdmModel GetEdmModel() {
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Student>("Students");
builder.EntitySet<Course>("Courses");
return builder.GetEdmModel();
}
I put my Entities instead of my ViewModels there. This is the fixed code:
private static IEdmModel GetEdmModel() {
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<StudentVM>("Students");
builder.EntitySet<CourseVM>("Courses");
return builder.GetEdmModel();
}
Now it's working as expected

In EF Code First, How to have ApplicationUser UserId as foreign key in a custom entity?

My Custom Entity:
public class Order
{
[Key,Column(Order=0)]
public int OrderId { get; set; }
//Other properties
public string UserId { get; set; }
[ForeignKey("UserId")]
public virtual ApplicationUser User { get; set; }
}
ApplicationUser Class:
public class ApplicationUser : IdentityUser
{
//one to many relation
public virtual List<Sandwich.Order>Order { get; set; }
public async Task<ClaimsIdentity>
GenerateUserIdentityAsync(UserManager<ApplicationUser> manager){..}
}
I have two DbContexts (One default of AppUser and One I created):
public class ADbContext : DbContext
{
public ADbContext() : base("DefaultConnection")
{
}
public DbSet<Toppings> ToppingsDbset { get; set;}
//I had to comment the line below to in order to work with ToppingDBset but then I can't work with OrderDBSet
//public DbSet<Order> OrderDbSet { get; set; }
}
//Default AppDbContext
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
When I run it just working with ApplicationDbContext it works fine and creates following table with all the relationships.
enter image description here
My problem: is when I try to work with ADbContext with un-commented public DbSet<Order> OrderDbSet { get; set; }
{"One or more validation errors were detected during model generation:\r\n\r\n.IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType.\r\n.IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined
Solutions I tried:
//Adding following method on ADbContext
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
}
I am trying to have all tables created in one Database. I am using EF6.
try this in OnModelCreating(DbModelBuilder modelBuilder):
modelBuilder.Entity()
.HasMany(c => c.Order)
.WithOne(e => e.ApplicationUser);
refrence
Solved :
In DbContext file, I added OrderDbSet within ApplicationDbContext class
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<Order> OrderDbset { get; set; }
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
}

exception:"type was not mapped" in entityframework codefirst with layers

i'm trying to apply LAYERS Concept on demo project developed using mvc and entity framework both
Data Annotations : for validations in Data Access Layer and
Fluent API : for mapping and tables relations
Problem : DbContext didn't Create DB and there is a Runtime Exception :
The type 'Domain.DataLayer.Member' was not mapped. Check that the type has not been explicitly excluded by using the Ignore method or NotMappedAttribute data annotation. Verify that the type was defined as a class, is not primitive, nested or generic, and does not inherit from EntityObject.
Code : my solutions consists of :
1- class library (Domain.Classes project): where i wrote all of my classes
public class Member
{
public int Id { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string FullName { get; set; }
}
2- DAL (Domain.DataLayer project): also another class library and i referenced domain.classes
namespace Domain.DataLayer.Repositories
{
[MetadataType(typeof(MemberMetadata))]
public partial class Member : Classes.Member , IValidatableObject
{
public Member()
{
Tasks = new HashSet<Task>();
History = new HashSet<Commint>();
}
public string ConfirmPassword { get; set; }
public HashSet<Task> Tasks { get; set; }
public HashSet<Commint> History { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var result = new List<ValidationResult>();
if (!string.Equals(Password,ConfirmPassword))
{
result.Add(new ValidationResult("mismatch pwsd", new[] {"ConfirmPassword" }));
}
return result;
}
}
}
and i used repository pattern :
public class MemberRepository : IRepository<Member>
{
public Task<IQueryable<Member>> GetAllEntities()
{
return Task<IQueryable<Member>>.Factory.StartNew(() => new Context().Members.AsQueryable());
}
}
3-BLL : for sake of simplicity : there is no Business Logic Layer
4- PL (Domain.Application MVC Project) : Member Controller :
public async Task<ActionResult> Index()
{
var members = await _repository.GetAllEntities();
return View(members);
}
Note : i depended on DbContext to create DB with name like : Domain.DataLayer.Context but it didn't craete DB so i created the DB and passed the connectionString through Context constructor like this :
namespace Domain.DataLayer
{
public class Context : DbContext
{
public Context(): base("InterviewDemo") // i tried also base("name=InterviewDemo")
{
}
public DbSet<Member> Members { get; set; }
public DbSet<Task> Tasks { get; set; }
public DbSet<Commint> TaskHistory { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new MemberConfig());
modelBuilder.Configurations.Add(new TaskConfig());
modelBuilder.Configurations.Add(new CommintConfig());
base.OnModelCreating(modelBuilder);
}
}
}

Sharp Architecture issue with EntityWithTypedId

I wish to use Guid comb for my identity. I've added the EntityWithTypedId interface to my class which cause my table not to persist. ie using nh prof i can see the SaveOrUpdate method is not called. If i just use the Entity interface i can see it in the profiler.
public class Application : EntityWithTypedId<Guid>
{
public virtual string Name { get; set; }
public virtual string CreatedByUserName { get; set; }
public virtual string ModifiedByUserName { get; set; }
public virtual DateTime Created { get; set; }
public virtual DateTime Modified { get; set; }
}
public class ApplicationQuery : NHibernateQuery, IApplicationQuery
{
public void Update(Application application)
{
Session.SaveOrUpdate(application);
}
}
public class ApplicationMap : IAutoMappingOverride<Application>
{
public void Override(AutoMapping<Application> mapping)
{
mapping.Table("Application");
mapping.Id(x => x.Id, "Id").GeneratedBy.GuidComb();
}
}
Controller
[HttpPost]
[ActionName("Edit")]
public ActionResult EditPost(Application application)
{
var updateApplication = new Application();
updateApplication.Created = DateTime.Now;
updateApplication.Modified = DateTime.Now;
_applicationQuery.Update(updateApplication);
return RedirectToAction("Index");
}
I fixed this by updating my mapping to the following.
public void Override(AutoMapping<Application> mapping)
{
mapping.Table("Application");
mapping.Id(x => x.Id, "Id").GeneratedBy.GuidComb().UnsavedValue(Guid.Empty);
}
See here for more info.
http://s274.codeinspot.com/q/1486941