Deploying codefirst is not creating all table fields - entity-framework

Im having some issues trying to deploy a code first based mvc4 application to azure.
It works fine when creating a localdb however when trying to deploy to azure the UserProfile table only Username & UserId fields are created.
My model looks like
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public Guid ConsumerId { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public bool IsMale { get; set; }
public string Mobile { get; set; }
[DefaultValue(false)]
public bool IsSmsVerified { get; set; }
public string SmsVerificationCode { get; set; }
}
Context
public class UsersContext : DbContext
{
public UsersContext()
: base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<ExternalUserInformation> ExternalUsers { get; set; }
}
Configuration
internal sealed class Configuration : DbMigrationsConfiguration<Web.Models.UsersContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(Web.Models.UsersContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
Is there a magic switch somewhere that I need to turn on?

Related

Entity Framework always adds two records in the tables

I'm implementing an ASP.NET Core 3.1 app. I have implemented following code to insert record in SQL Server database via EF Core but each time I save data, it inserts two records in PersonRequester and Requester table. I appreciate if anyone suggests me how I can prevent reinserting records.
Requester ap = new Requester();
ap.Address = RequesterViewModel.Requestervm.Address;
ap.RequesterType = RequesterViewModel.Requestervm.RequesterType;
ap.Description = RequesterViewModel.Requestervm.Description;
ap.Name = RequesterViewModel.Requestervm.Name;
var pa = new PersonRequester()
{
BirthCertificateNo = RequesterViewModel.personRequestervm.BirthCertificateNo,
IssuePlace = RequesterViewModel.personRequestervm.IssuePlace,
NationalCode = RequesterViewModel.personRequestervm.NationalCode,
Requester = ap
};
using (var context = new DBContext())
{
context.PersonRequester.Attach(pa);
try
{
context.SaveChanges();
}
catch (Exception e)
{
throw e;
}
}
public partial class Requester
{
public Requester()
{
PersonRequester = new HashSet<PersonRequester>();
}
public int RequesterId { get; set; }
public int RequesterType { get; set; }
public string Address { get; set; }
public string Description { get; set; }
public string Name { get; set; }
public virtual EntityType RequesterTypeNavigation { get; set; }
public virtual ICollection<PersonRequester> PersonRequester { get; set; }
}
public partial class PersonRequester
{
public int RequesterId { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public int RequesterType { get; set; }
public string NationalCode { get; set; }
public string BirthCertificateNo { get; set; }
public string IssuePlace { get; set; }
public virtual Requester Requester { get; set; }
public virtual EntityType RequesterTypeNavigation { get; set; }
}

EF: validation error for 1:0..1 relationship in data model with navigation properties

I have this simple data model of some reservations and theirs cancellations:
[Table("ReservationCreation")]
public class ReservationCreation
{
[Key()]
public int ReservationCreationId { get; set; }
[InverseProperty("ReservationCreation")]
public virtual ReservationCancellation ReservationCancellation { get; set; }
}
[Table("ReservationCancellation")]
public class ReservationCancellation
{
[Key()]
[ForeignKey("ReservationCreation")]
public int ReservationCancellationId { get; set; }
[Required]
[ForeignKey("ReservationCancellationId")]
[InverseProperty("ReservationCancellation")]
public virtual ReservationCreation ReservationCreation { get; set; }
}
public class DbContext : System.Data.Entity.DbContext
{
public DbContext() : base(#"DefaultConnection") { }
public DbSet<ReservationCancellation> ReservationCancellation { get; set; }
public DbSet<ReservationCreation> ReservationCreation { get; set; }
}
internal sealed class Configuration : DbMigrationsConfiguration<DbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
}
Here is the code of the test. First the reservation is created and then it is cancelled.
When the cancellation record is being saved into database then an exception is thrown "The ReservationCreation field is required".
How can I create cancellation record only from the reservation's ID and at the same time have the navigation properties defined?
class Program
{
static void Main(string[] args)
{
int reservationId;
// create reservation
using (var db = new DbContext())
{
var reservation =
db.ReservationCreation.Add(
new ReservationCreation());
db.SaveChanges();
reservationId = reservation.ReservationCreationId;
}
// cancel reservation by its Id
using (var db = new DbContext())
{
var cancellation =
db.ReservationCancellation.Add(
new ReservationCancellation
{
ReservationCancellationId = reservationId
});
try
{
// an exception is thrown
db.SaveChanges();
}
catch(DbEntityValidationException ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
foreach (var err in ex.EntityValidationErrors.SelectMany(x_ => x_.ValidationErrors))
System.Diagnostics.Debug.WriteLine($"!!!ERROR!!! {err.PropertyName}: {err.ErrorMessage}");
}
}
}
}
I did not find any way how to modify the data model annotations. If I remove [Required] from ReservationCreation property then I am not able to create the migration {or connect to the database with that data model).
Your mixing things up in your ReservationCancellation model.
In your ReservationCreation property you are referring to the primary key entity instead of the ReservationCreation property.
Try this.
[Table("ReservationCancellation")]
public class ReservationCancellation
{
[Key()]
public int ReservationCancellationId { get; set; }
[ForeignKey("ReservationCreation")]
public int ReservationCreationId { get; set; }
[Required]
public virtual ReservationCreation ReservationCreation { get; set; }
}
Update
Since you want only one cancellation per creation, you can do this using a simpler model.
[Table("ReservationCreation")]
public class ReservationCreation
{
[Key()]
public int ReservationCreationId { get; set; }
public virtual ReservationCancellation ReservationCancellation { get; set; }
}
[Table("ReservationCancellation")]
public class ReservationCancellation
{
[Key()]
public int ReservationCancellationId { get; set; }
public virtual ReservationCreation ReservationCreation { get; set; }
}
I followed the recommendations from #dknaack and my final solution of this problem is this data model:
[Table("ReservationCreation")]
public class ReservationCreation
{
[Key()]
public int ReservationCreationId { get; set; }
[InverseProperty("ReservationCreation")]
public virtual ReservationCancellation ReservationCancellation { get; set; }
}
[Table("ReservationCancellation")]
public class ReservationCancellation
{
[Key()]
[ForeignKey("ReservationCreation")]
public int ReservationCancellationId { get; set; }
[ForeignKey("ReservationCancellationId")]
public virtual ReservationCreation ReservationCreation { get; set; }
}

Entity Framework error while saving changes

I'm new to Entity Framework. At the moment I'm having a problem - when I try to insert a new User object into the database (using method RegisterNewUser), I keep getting an error:
Violation of PRIMARY KEY constraint 'PK__Users__3214EC07705D23AE'. Cannot insert duplicate key in object 'dbo.Users'. The duplicate key value is (0).
There are some similar questions here, but none of these answers have helped me.
public void RegisterNewUser(String uName, String uPass, String fName, String lName, String email)
{
User user = new User();
user.Username = uName;
user.Password = uPass;
user.FirstName = fName;
user.LastName = lName;
user.Email = email;
Time time = new Time();
time.Time1 = DateTime.Now;
user.Times.Add(time);
ur.AddUser(user);
}
Time and User objects:
public partial class Time
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int UserId { get; set; }
public System.DateTime Time1 { get; set; }
public virtual User User { get; set; }
}
public partial class User
{
public User()
{
this.Times = new HashSet<Time>();
}
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public virtual ICollection<Time> Times { get; set; }
}
Repository file
public class UsersRepository
{
UsersDBContext userDBContext = new UsersDBContext();
public List<User> GetUsers()
{
return userDBContext.Users.Include("Times").ToList();
}
public void AddUser(User user)
{
userDBContext.Users.Add(user);
userDBContext.SaveChanges();
}
}
And context
public partial class UsersDBContext : DbContext
{
public UsersDBContext() : base("name=UsersDBContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Time> Times { get; set; }
public virtual DbSet<User> Users { get; set; }
}
I have no idea how to solve this so any suggestions would be very helpful
set a value of Id field
or
define the Id field as autoincrement

Entity framework replaces delete+insert with an update. How to turn it off

I want to remove a row in database and insert it again with the same Id, It sounds ridiculous, but here is the scenario:
The domain classes are as follows:
public class SomeClass
{
public int SomeClassId { get; set; }
public string Name { get; set; }
public virtual Behavior Behavior { get; set; }
}
public abstract class Behavior
{
public int BehaviorId { get; set; }
}
public class BehaviorA : Behavior
{
public string BehaviorASpecific { get; set; }
}
public class BehaviorB : Behavior
{
public string BehaviorBSpecific { get; set; }
}
The entity context is
public class TestContext : DbContext
{
public DbSet<SomeClass> SomeClasses { get; set; }
public DbSet<Behavior> Behaviors { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Entity<SomeClass>()
.HasOptional(s => s.Behavior)
.WithRequired()
.WillCascadeOnDelete(true);
}
}
Now this code can be executed to demonstrate the point
(described with comments in the code below)
using(TestContext db = new TestContext())
{
var someClass = new SomeClass() { Name = "A" };
someClass.Behavior = new BehaviorA() { BehaviorASpecific = "Behavior A" };
db.SomeClasses.Add(someClass);
// Here I have two classes with the state of added which make sense
var modifiedEntities = db.ChangeTracker.Entries()
.Where(entity => entity.State != System.Data.Entity.EntityState.Unchanged).ToList();
// They save with no problem
db.SaveChanges();
// Now I want to change the behavior and it causes entity to try to remove the behavior and add it again
someClass.Behavior = new BehaviorB() { BehaviorBSpecific = "Behavior B" };
// Here it can be seen that we have a behavior A with the state of deleted and
// behavior B with the state of added
modifiedEntities = db.ChangeTracker.Entries()
.Where(entity => entity.State != System.Data.Entity.EntityState.Unchanged).ToList();
// But in reality when entity sends the query to the database it replaces the
// remove and insert with an update query (this can be seen in the SQL Profiler)
// which causes the discrimenator to remain the same where it should change.
db.SaveChanges();
}
How to change this entity behavior so that delete and insert happens instead of the update?
A possible solution is to make the changes in 2 different steps: before someClass.Behavior = new BehaviorB() { BehaviorBSpecific = "Behavior B" }; insert
someClass.Behaviour = null;
db.SaveChanges();
The behaviour is related to the database model. BehaviourA and B in EF are related to the same EntityRecordInfo and has the same EntitySet (Behaviors).
You have the same behaviour also if you create 2 different DbSets on the context because the DB model remains the same.
EDIT
Another way to achieve a similar result of 1-1 relationship is using ComplexType. They works also with inheritance.
Here an example
public class TestContext : DbContext
{
public TestContext(DbConnection connection) : base(connection, true) { }
public DbSet<Friend> Friends { get; set; }
public DbSet<LessThanFriend> LessThanFriends { get; set; }
}
public class Friend
{
public Friend()
{Address = new FullAddress();}
public int Id { get; set; }
public string Name { get; set; }
public FullAddress Address { get; set; }
}
public class LessThanFriend
{
public LessThanFriend()
{Address = new CityAddress();}
public int Id { get; set; }
public string Name { get; set; }
public CityAddress Address { get; set; }
}
[ComplexType]
public class CityAddress
{
public string Cap { get; set; }
public string City { get; set; }
}
[ComplexType]
public class FullAddress : CityAddress
{
public string Street { get; set; }
}

Entity Framework 4.1 : The navigation property 'BusinessUser' declared on type 'Login' has been configured with conflicting multiplicities

I am having two entities
BusinessUser { Id(PK), Name,...}
Login { BusinessUserID(PK, FK), Email, Password, etc...}
Relationship between BusinessUser and Login is one-to-zero/one.
I am having following configurations
In BusinessUser EF configuration class
this.HasOptional(bu => bu.LoginInfo)
.WithOptionalPrincipal(l => l.BusinessUser);
In Login EF configuration class
this.HasRequired(l => l.BusinessUser)
.WithOptional(bu => bu.LoginInfo);
I am getting following exception
The navigation property 'BusinessUser' declared on type 'Login' has been configured
with conflicting multiplicities.
Where I am wrong with my one-to-one/zero configuration in EF 4.1 code first.
Update 1 : Following are my class structure
public class BusinessUser {
public virtual int ID { get; set; }
public virtual int BusinessID { get; set; }
public virtual Business Business { get; set; }
public Login LoginInfo { get; set; }
}
public class Login {
public virtual int BusinessUserID { get; set; }
public virtual string Email { get; set; }
public virtual string Password { get; set; }
public BUsinessUser BusinessUserInfo { get; set; }
}
Also I am looking for bi-directional.
Your BusinessUser must have relation configured as:
this.HasOptional(bu => bu.LoginInfo)
.WithRequired(l => l.BusinessUser);
Both configuration must be same (actually only one is needed) and the first configuration is incorrect because it is trying to define 0..1 - 0..1 relation.
How have you structured your classes ? Here's a sample with a relationship one-to-one/zero defined.
The result is :
BusinessUser { Id(PK), Name,...}
Login { BusinessUserID(PK, FK), Email, Password, etc...}
public class BusinessUser
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public virtual LoginInfo LoginInfo { get; set; }
}
public class LoginInfo
{
public int BusinessUserId { get; set; }
public virtual BusinessUser BusinessUser { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
Here is the DbContext and the Initializer
public class MyContext : DbContext
{
public DbSet<BusinessUser> BusinessUsers { get; set; }
public DbSet<LoginInfo> LoginInfos { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
//We define the key for the LoginInfo table
modelBuilder.Entity<LoginInfo>().HasKey(x => x.BusinessUserId);
modelBuilder.Entity<LoginInfo>().HasRequired(bu => bu.BusinessUser);
}
}
public class MyInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
protected override void Seed(MyContext context)
{
var businessUser = new BusinessUser();
businessUser.Email = "mymail#email.com";
businessUser.Name = "My Name";
businessUser.LoginInfo = new LoginInfo(){Username = "myusername", Password ="mypassword"};
context.BusinessUsers.Add(businessUser);
context.SaveChanges();
}
}