Fluent API not creating Identity Specification (Is Identity) in SQL Server - sql-server-2008

I have an MVC4 application that is using code first. I have created 3 models that I wish to use to keep track of my clients Associates each with a designation of AssociateType (Distributors or Retailers) each Associate also has a deignated Region (North Florida or South Florida.
I started off by creating the following models and running update-database to create the tables in the database.
Associate.cs
namespace XXX.Models
{
public class Associate
{
public int AssociateID { get; set; }
[StringLength(50), Column(TypeName = "varchar")]
public string AssociateName { get; set; }
public int AddressNumber { get; set; }
[StringLength(50), Column(TypeName = "varchar")]
public string AddressStreet { get; set; }
[StringLength(20), Column(TypeName = "varchar")]
public string AddressCity { get; set; }
[StringLength(2), Column(TypeName = "varchar")]
public string State { get; set; }
[StringLength(10), Column(TypeName = "varchar")]
public string Zipcode { get; set; }
[StringLength(16), Column(TypeName = "varchar")]
public string MainPhoneNumber { get; set; }
[StringLength(60), Column(TypeName = "varchar")]
public string AssociateEmail { get; set; }
[StringLength(80), Column(TypeName = "varchar")]
public string AssociateWebsite { get; set; }
//See Corresponding Navigation Properties
[Display(Name = "Region")]
public int RegionID { get; set; }
[Display(Name = "AssociateType")]
public int AssociateTypeID { get; set; }
[StringLength(35), Column(TypeName = "varchar")]
public string ContactFirstName { get; set; }
[StringLength(35), Column(TypeName = "varchar")]
public string ContactLastName { get; set; }
[StringLength(16), Column(TypeName = "varchar")]
public string ContactPhoneNumber { get; set; }
[StringLength(60), Column(TypeName = "varchar")]
public string ContactEmail { get; set; }
public virtual Region Region { get; set; }
public virtual AssociateType AssociateType { get; set; }
}
AssociateType.cs
namespace XXX.Models
{
public class AssociateType
{
[ForeignKey("Associate")]
public int AssociateTypeID { get; set; }
[StringLength(50), Column(TypeName = "varchar")]
public string AssociateTypeName { get; set; }
public virtual Associate Associate { get; set; }
}
}
'Region.cs'
namespace XXX.Models
{
public class Region
{
public int RegionID { get; set; }
[StringLength(20), Column(TypeName = "varchar")]
public string RegionName { get; set; }
[Column(TypeName = "varchar(Max)")]
public string RegionDescription { get; set; }
public virtual Associate Associate { get; set; }
}
}
DBContext
namespace XXX.Models
{
public class XXXDb : DbContext
{
public XXXDb(): base("name=DefaultConnection")
{
}
public DbSet<Associate> Associates { get; set; }
public DbSet<AssociateType> AssociateType { get; set; }
public DbSet<Ingredient> Ingredients { get; set; }
public DbSet<Region> Regions { get; set; }
public DbSet<UserProfile> UserProfiles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Associate>().HasKey(a => a.AssociateID);
modelBuilder.Entity<Associate>().Property(a => a.AssociateID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Associate>().HasRequired(at => at.AssociateType)
.WithRequiredDependent();
modelBuilder.Entity<Associate>().HasRequired(r => r.Region)
.WithRequiredDependent();
modelBuilder.Entity<AssociateType>().HasKey(at => at.AssociateTypeID);
modelBuilder.Entity<AssociateType>().Property(at => at.AssociateTypeID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Region>().HasKey(r => r.RegionID);
modelBuilder.Entity<Region>().Property(r => r.RegionID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
}
My Tables are not being created with the IDENTITY SPECIFICATION (Is Identity) being set to Yes..... WHY IS THIS?? Because of this I cannot add any data to the tables or I get an error:
Cannot insert the value NULL into column 'RegionID', table 'XXXDb.dbo.Regions'; column does not allow nulls. INSERT FAILS.
My goal is to populate the Region & AssociateType tables with just a few rows of items.
Regions: (North Florida & South Florida)
AssociateTypes (Distributors & Retailers)
This way when I add an Associate during a CRUD operation I would have two drop downs that have the options (Distributors & Retailers) for AssociateType and (N or S Florida) for that associates Region.
Any help would be very much appreciated. I'm really getting frustrated with MVC. I have made it pretty far, but starting to get discouraged.

I did some test and here is the solution that work on my machine I just kept the navigation properties of your obejcts.
public class Associate
{
public int AssociateID { get; set; }
public int RegionID { get; set; }
public virtual Region Region { get; set; }
public int AssociateTypeID { get; set; }
public virtual AssociateType AssociateType { get; set; }
}
public class Region
{
public int RegionID { get; set; }
[StringLength(50), Column(TypeName = "varchar")]
public string IngredientNameEn { get; set; }
[Column(TypeName = "varchar(Max)")]
public string IngredientNameEs { get; set; }
public virtual List<Associate> Associates { get; set; }
}
public class AssociateType
{
public int AssociateTypeID { get; set; }
[StringLength(50), Column(TypeName = "varchar")]
public string AssociateTypeName { get; set; }
public virtual List<Associate> Associates { get; set; }
}
Then in the OnModelCreating you have to add the following two commands and this should generate the database that you want
modelBuilder.Entity<Region>().HasMany(a => a.Associates)
.WithRequired(r => r.Region).HasForeignKey(r => r.RegionID);
modelBuilder.Entity<AssociateType>().HasMany(a => a.Associates)
.WithRequired(r => r.AssociateType).HasForeignKey(r => r.AssociateTypeID);
and in the class constructor you may add this code
public XXXDb(): base("name=DefaultConnection")
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<XXXDb>());
Database.Initialize(force: true);
}

Related

How can I create a new database using Entity Framework Code First programmatically?

I have an MVC application that companies can be sign up and have some datas. When a company signed up, I want to create a database for company signed up, but I want to use entity framework with MySQL. How can I do this?
This is my DbContext;
[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class CompanyModel : DbContext
{
public virtual DbSet<siteler> siteler { get; set; }
public virtual DbSet<kazanlar> kazanlar { get; set; }
public CompanyModel() : base()
{
}
}
public class siteler
{
[Key]
public int site_id { get; set; }
[Required]
[StringLength(45)]
public string site_adi { get; set; }
[Required]
public int il_id { get; set; }
[Required]
public int ilce_id { get; set; }
[Required]
[StringLength(140)]
public string adres { get; set; }
[Required]
public DateTime olusturma_tarihi { get; set; }
[Required]
[DefaultValue(true)]
public bool aktif { get; set; }
}
public class kazanlar
{
[Key]
public int kazan_id { get; set; }
[Required]
[StringLength(12)]
[Index(IsUnique = true)]
public string kazan_no { get; set; }
[Required]
public int site_id { get; set; }
[Required]
public decimal okuma_ucreti { get; set; }
}
This is my MySQL Connection String
<connectionStrings>
<add name="mysqlroot" connectionString="Server=127.0.0.1;Port=3306;Uid=root;Pwd=xxxx;"/>
</connectionStrings>

Web API, C#, Json Objects, Views

I have some issues with displaying data as a Json object in this ASP.NET Web API project. It is my first try, I don't have Views, I am gonna use Postman for testing. Can you give me some diretions how to display the model as an Json Object?
//UserController
public class UsersController : ApiController
{
private LearnToLearnContext db = new LearnToLearnContext();
private BaseRepository<Users> _repository = null;
public UsersController()
{
this._repository = new BaseRepository<Users>();
}
// GET: api/Users
[ResponseType(typeof(Users))]
public IHttpActionResult GetUsers()
{
var user = _repository.GetAll();
var bindingModel = Mapper.Map<UsersBindingModels>(user);
return Ok(bindingModel);
}
}
//UserModel
public class Users
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Unique]
[Required]
public string Email { get; set; }
[Required]
public string Password { get; set; }
public bool IsTeacher { get; set; }
public virtual List<Courses> Courses { get; set; }
}
//UserBindingModel
public class UsersBindingModels
{
[Required]
public string name { get; set; }
[Unique]
[Required]
public string email { get; set; }
[Required]
public string password { get; set; }
public bool isTeacher { get; set; }
public virtual List<Courses> Courses { get; set; }
}

Code first generating strange column

I have an MVC 4 application that is using code first to generate tables and columns in my SQL Server DB. I am trying to figure out how I ended up with an additional TABLE that was not intended. I have looked through some questions but not found the exact same problem I am having. I will try to explain this simply.
I have added a model called Associate which keeps track of associates that my client does business with. Each Associate needs a foriegn key of AssociateTypedID and RegionID.
namespace XXX.Models
{
public class Associate
{
public int AssociateId { get; set; }
public string AssociateName { get; set; }
public int AddressNumber { get; set; }
public string AddressStreet { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zipcode { get; set; }
public string MainPhoneNumber { get; set; }
public string AssociateEmail { get; set; }
public string AssociateWebsite { get; set; }
public string ContactFirstName { get; set; }
public string ContactLastName { get; set; }
public string ContactPhoneNumber { get; set; }
public string ContactEmail { get; set; }
public int RegionId { get; set; }
public int AssociateTypeId { get; set; }
public virtual ICollection<AssociateType> AssociateTypes { get; set; }
public virtual ICollection<Region> Regions { get; set; }
}
}
AND
namespace XXX.Models
{
public class AssociateType
{
public int AssociateTypeId { get; set; }
public string AssociateTypeName { get; set; }
public virtual ICollection<Associate> Associates { get; set; }
}
}
AND
namespace XXX.Models
{
public class Region
{
public int RegionId { get; set; }
public int RegionName { get; set; }
public int RegionDescription { get; set; }
public virtual ICollection<Associate> Associates { get; set; }
}
}
AND
namespace XXX.Models
{
public class XXXDb : DbContext
{
public XXXDb(): base("name=DefaultConnection")
{
}
public DbSet<Associate> Associates { get; set; }
public DbSet<AssociateType> AssociateTypes { get; set; }
public DbSet<Region> Regions { get; set; }
}
}
So I have updated my code above and I'm getting very close to where I need to be in my database. I have the following tables generated.
Associates, AssociateTypes & Regions (each of them have the columns I would expect)
BUT I now have a new table called RegionAssociates which has the following columns:
Region_RegionId (int) & Associate_AssociateId (int)
This table was not expected or needed in my schema.
Your classes doesn't match your description of the model. You are saying
Each Associate can have a designation of AssociateType
I suppose that the same AssociateType can be assigned to more Associates, so there should be 1:N relationship between AssociateType and Associate.
But the Associate class defines the relationship the other way around - by convention public virtual ICollection<AssociateType> AssociateType { get; set; } creates 1:N relationship between Associate and AssociateType.
the correct definition of your classes would be
public class Associate
{
public int AssociateId { get; set; }
public string AssociateName { get; set; }
public int AddressNumber { get; set; }
public string AddressStreet { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zipcode { get; set; }
public string MainPhoneNumber { get; set; }
public string AssociateEmail { get; set; }
public string AssociateWebsite { get; set; }
public int RegionId { get; set; }
public int AssociateTypeId { get; set; }
public virtual AssociateType AssociateType { get; set; }
public string ContactFirstName { get; set; }
public string ContactLastName { get; set; }
public string ContactPhoneNumber { get; set; }
public string ContactEmail { get; set; }
public virtual ICollection<Region> Regions { get; set; }
}
public class AssociateType
{
public int AssociateTypeId { get; set; }
public string AssociateTypeName { get; set; }
public virtual ICollection<Associate> Associates { get; set; }
}
Can't say for sure what is missing from your configuration as you did't post it, but if you are using the fluent api something like this should fix the problem:
modelBuilder.Entity<AssociateType>()
.HasKey(t => t.AssociateTypeId);
modelBuilder.Entity<Associate>()
.HasRequired(t => t.AssociateType)
.WithRequiredPrincipal(t => t.Associate);
The above is adapted from this article http://msdn.microsoft.com/en-us/data/jj591620.aspx

Entity Framework 4.1 two FKs pointing to same table

I ran into an issue when adding two navigation properties of the same type in a model, giving me this error :
System.Data.SqlClient.SqlException:
Invalid column name : 'Createur_IdUtilisateur'.
Invalid column name : 'Proprietaire_IdUtilisateur'.
This is the code (broken) that I have :
public class Billet
{
[Key]
public int IdBillet { get; set; }
public int IdMandat { get; set; }
public string Titre { get; set; }
[AllowHtml]
public string Description { get; set; }
public int IdUtilisateurCreateur { get; set; }
public int IdUtilisateurProprietaire { get; set; }
public DateTime DateCreation { get; set; }
public DateTime? DateFermeture { get; set; }
public int EstimationTemps { get; set; }
public int Priorite { get; set; }
public bool FermetureParCreateur { get; set; }
public virtual ICollection<Intervention> Interventions { get; set; }
public virtual Mandat Mandat { get; set; }
public virtual Utilisateur Createur { get; set; }
public virtual Utilisateur Proprietaire { get; set; }
}
public class Utilisateur
{
[Key]
public int IdUtilisateur { get; set; }
public int IdUtilisateurRole { get; set; }
public string Courriel { get; set; }
public string Nom { get; set; }
public string Password { get; set; }
public bool Actif { get; set; }
public virtual UtilisateurRole Role { get; set; }
}
And this is what the relationships look like in the database.
I've read about [InverseProperty], but I'm not sure how I would go about implementing that in my situation. Do I need to add reverse navigation properties in my Utilisateur class to make this work?
Shortly after asking I realized my mistake, this is how I fixed it :
public class Entities : DbContext
{
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
...
modelBuilder.Entity<Billet>()
.HasRequired(b => b.Createur)
.WithMany()
.HasForeignKey(b => b.IdUtilisateurCreateur);
modelBuilder.Entity<Billet>()
.HasRequired(b => b.Proprietaire)
.WithMany()
.HasForeignKey(b => b.IdUtilisateurProprietaire);
}
}

Entity Framework Code 1st - Mapping many-to-many with extra info

I've looked through several of the questions here and am not quite connecting all the (mental) dots on this. I would appreciate some help.
My Models (code first):
public class cgArmorial
{
[Key]
[Display(Name = "Armorial ID")]
public Guid ArmorialID { get; set; }
[Display(Name = "User ID")]
public Guid UserId { get; set; }
public string Name { get; set; }
public string DeviceUrl { get; set; }
public string Blazon { get; set; }
public virtual ICollection<cgArmorialAward> ArmorialAwards { get; set; }
}
public class cgArmorialAward
{
public cgArmorial Armorial { get; set; }
public cgAward Award { get; set; }
public DateTime AwardedOn { get; set; }
}
public class cgAward
{
[Key]
[Display(Name = "Award ID")]
public Guid AwardID { get; set; }
public string Name { get; set; }
public string Group { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
public string Blazon { get; set; }
public virtual ICollection<cgArmorialAward> ArmorialAwards { get; set; }
}
Then in my Context class I have (last 2 entries):
public class Context : DbContext
{
public DbSet<cgUser> Users { get; set; }
public DbSet<cgEvent> Events { get; set; }
public DbSet<cgEventType> EventTypes { get; set; }
public DbSet<cgArmorial> Armorials { get; set; }
public DbSet<cgAward> Awards { get; set; }
public DbSet<cgArmorialAward> ArmorialAwards { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<cgUser>()
.HasMany<cgEvent>(e => e.EventAutocrats)
.WithMany(u => u.EventAutocrats)
.Map(m =>
{
m.ToTable("EventAutocrats");
m.MapLeftKey("UserId");
m.MapRightKey("EventId");
});
modelBuilder.Entity<cgUser>()
.HasMany<cgEvent>(e => e.EventStaff)
.WithMany(u => u.EventStaff)
.Map(m =>
{
m.ToTable("EventStaff");
m.MapLeftKey("UserId");
m.MapRightKey("EventId");
});
modelBuilder.Entity<cgArmorialAward>()
.HasRequired(a => a.Armorial)
.WithMany(b => b.ArmorialAwards);
modelBuilder.Entity<cgArmorialAward>()
.HasRequired(a => a.Award)
.WithMany(); // b => b.ArmorialAwards
}
}
I am getting this error when I try to run:
System.Data.Edm.EdmEntityType: : EntityType 'cgArmorialAward' has no
key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet �ArmorialAwards�
is based on type �cgArmorialAward� that has no keys defined.
Well, as the exception says: You don't have a key defined on your entity cgArmorialAward. Every entity must have a key. Change it to the following:
public class cgArmorialAward
{
[Key, Column(Order = 0)]
[ForeignKey("Armorial")]
public Guid ArmorialID { get; set; }
[Key, Column(Order = 1)]
[ForeignKey("Award")]
public Guid AwardID { get; set; }
public cgArmorial Armorial { get; set; }
public cgAward Award { get; set; }
public DateTime AwardedOn { get; set; }
}
The fields in the composite key are foreign keys to the other two tables at the same time, hence the ForeignKey attribute. (I'm not sure if conventions would detect this automatically because you have non-standard names ("cgXXX" for the classes and "XXXId" for the foreign key properties). On the other hand the property names Armorial and Award match the foreign key property names. I'm not sure if EF conventions would consider this. So, perhaps the ForeignKey attribute is not necessary but at least it's not wrong.)