Entity Framework Code First relation in one table - entity-framework

I've a problem with creating a relation in one table. I have a UserProfile class. An another user can by only created by existing user. So I want to have fields with information about who created user and when the user was created. Maybe the code will say more :)
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
[Required, MaxLength(30)]
public string UserName { get; set; }
[Column(TypeName = "date")]
[Display(Name = "Data ważności")]
public DateTime ExpirationDate { get; set; }
[DataType(DataType.DateTime)]
[Display(Name = "Data dodania")]
[Column(TypeName = "datetime")]
public DateTime sysRegDate { get; set; }
[ForeignKey("sysRegUser")]
public int? sysRegUserId { get; set; }
[DataType(DataType.DateTime)]
[Column(TypeName = "datetime")]
public DateTime sysModDate { get; set; }
[ForeignKey("sysModUser")]
public int? sysModUserId { get; set; }
public virtual UserProfile sysRegUser { get; set; }
public virtual UserProfile sysModUser { get; set; }
}
But when I'm creating a migration I get error:
System.Data.Entity.ModelConfiguration.ModelValidationException: One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 'UserProfile_sysModUser_Source' in relationship 'UserProfile_sysModUser'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.
Thanks in advance for answers.

I have used this code to create a parent-child relation, maybe it helps:
public class MyModel
{
public int Id {get;set;}
// ...
public int? ParentId {get;set;}
public virtual MyModel Parent {get;set;}
public virtual IList<MyModel> Children {get;set;}
}
And in the DbContext:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyModel>().HasOptional(p => p.Parent).WithMany(p => p.Children).HasForeignKey(p => p.ParentId);
modelBuilder.Entity<MyModel>().Property(p => p.ParentId).HasColumnName("Parent");
}

Related

Can't set the Relation between 2 DB Models

I Got This Issue:
I Have the Application User Class Like This
public class ApplicationUser : IdentityUser
{
public ROLES Role { get; set; }
public int? CompanyId { get; set; }
public int? AreaId { get; set; }
public string Document { get; set; }
public bool Enable { get; set; }
[ForeignKey("CompanyId")]
public virtual Company Company { get; set; }
[ForeignKey("AreaId")]
public virtual Area Area { get; set; }
public virtual ICollection Measures { get; set; }
}
And I Got this another Model:
public class Area
{
public int AreaId { get; set; }
public string AreaName { get; set; }
public int CompanyId { get; set; }
public string UserId { get; set; }
[ForeignKey("CompanyId")]
public virtual Company Company { get; set; }
[Key, ForeignKey("UserId")]
public ApplicationUser ApplicationUser { get; set; }
}
And when i try to:
add-migration
the PM Console throws:
Unable to determine the principal end of an association between the types 'x.Models.ApplicationUser' and 'x.Models.Area'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.
I have been trying all day but I can't find a way to tell the Entity Framework to recognize the relation.
Any ideas?
Thanks for reading
Add Attribute for AreaId in Area class
[Key]
public int AreaId { get; set; }
and if you want 1-1 relationship for ApplicationUser and Area update your code like
[Unique]
[ForeignKey("UserId")]
public ApplicationUser ApplicationUser { get; set; }
The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations
This Post give me the Answer I Need!!!
It's pretty hard to find...
So I let you the post here...
Thanks for all of your help!

EntityType 'CustomUserLogin' has no key defined. Define the key for this EntityType

I've just started a new project in Web Forms because I thought it'd be quicker than learning MVC, but how wrong was I! I'm struggling with the Identity aspect of my project. I've followed this link here: http://www.asp.net/identity/overview/extensibility/change-primary-key-for-users-in-aspnet-identity
And it all compiles ok and works (my ID column is now an integer).
So I've created a new class for a 'Property' context:
using System.Collections.Generic;
using System.Data.Entity;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.AspNet.Identity.EntityFramework;
using System.Web.Security;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace MyApp.Models
{
public class PropertyContext : DbContext
{
public PropertyContext()
: base("DefaultConnection")
{
}
public DbSet<Property> Property { get; set; }
}
public class Property
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity), ScaffoldColumn(false)]
public int PropertyID { get; set; }
//[Required, StringLength(128)]
//public string OwnerID { get; set; }
// [ForeignKey("OwnerID")]
//public virtual ApplicationUser ApplicationUser { get; set; }
//[ForeignKey("OwnerID")]
//public int OwnerID { get; set; }
// public virtual ApplicationUser ApplicationUser { get; set; }
public int OwnerID { get; set; }
[ForeignKey("OwnerID")]
public virtual ApplicationUser ID { get; set; }
[Required, StringLength(255), Display(Name = "Address 1")]
public string Address1 { get; set; }
[Required, StringLength(255), Display(Name = "Address 2")]
public string Address2 { get; set; }
[Required, StringLength(255), Display(Name = "Address 3")]
public string Address3 { get; set; }
[Required, StringLength(255), Display(Name = "Town/City")]
public string Settlement { get; set; }
[Required, StringLength(255), Display(Name = "County")]
public string County { get; set; }
[Required, StringLength(255), Display(Name = "Post Code")]
public string PostCode { get; set; }
[Required, StringLength(255), Display(Name = "Country")]
public string Country { get; set; }
}
}
Whereby I'm trying to make a new int column called 'OwnerID' a foreign key into the 'AspNetUser' table's ID column. When i build my project, it builds fine. However when I try to add a migration I get this:
MyApp.Models.CustomUserLogin: : EntityType 'CustomUserLogin' has no key defined. Define the key for this EntityType.
MyApp.Models.CustomUserRole: : EntityType 'CustomUserRole' has no key defined. Define the key for this EntityType.
CustomUserLogins: EntityType: EntitySet 'CustomUserLogins' is based on type 'CustomUserLogin' that has no keys defined.
CustomUserRoles: EntityType: EntitySet 'CustomUserRoles' is based on type 'CustomUserRole' that has no keys defined.
So in my ApplicationDbContext I've added this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>().ToTable("Users").HasKey<int>(u => u.Id);
modelBuilder.Entity<CustomUserRole>().ToTable("UserRoles").HasKey(ur => new { ur.RoleId, ur.UserId });
modelBuilder.Entity<CustomUserLogin>().ToTable("UserLogins").HasKey<int>(ul => ul.UserId);
modelBuilder.Entity<CustomUserClaim>().ToTable("UserClaims").HasKey<int>(uc => uc.Id);
modelBuilder.Entity<CustomRole>().ToTable("Roles").HasKey<int>(r => r.Id);
}
and even this
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<CustomUserLogin>().HasKey(cul => cul.UserId);
modelBuilder.Entity<CustomUserRole>().HasKey(cur => cur.UserId);
But it still doesn't work. And to be quite honest I'm burning up a whole weekend by stabbing in the dark. I can't believe something as simple as creating a foreign key is so difficult in this Entity Framework environment.
Can anybody give me a pointer? Thanks.
I did exactly as you did.
Added Identity to my MVC Web Application
Changed the primary key to be an INT rather a GUID
Added an EmployeeProfile and a CustomerProfile to the ApplicationUser
I did not have to override OnModelCreating as I made my own changes to the database tables to support what I needed.
Added two new properties to the ApplicationUser class in IdentityModels.cs
public virtual CustomerProfile CustomerProfile { get; set; }
public virtual EmployeeProfile EmployeeProfile { get; set; }
I created the CustomerProfile and EmployeeProfile classes. Note the Data Annotations on the Id property of each class. The Id property is the ForeignKey property to guide the virtual User property back to the ApplicationUser.
public class EmployeeProfile
{
[Key, ForeignKey("User")]
public int Id { get; set; }
public DateTime HireDate { get; set; }
public DateTime BirthDate{ get; set; }
public virtual ApplicationUser User { get; set; }
}
public class CustomerProfile
{
[Key, ForeignKey("User")]
public int Id { get; set; }
public CustomerType CustomerType { get; set; }
public string Company { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public string WorkPhone { get; set; }
public string CustomerId { get; set; }
public string AccountType { get; set; }
public virtual ApplicationUser User { get; set; }
}
In my ApplicationDbContext class, I added the following lines of code:
public DbSet<CustomerProfile> CustomerProfile { get; set; }
public DbSet<EmployeeProfile> EmployeeProfile { get; set; }
Everything was working as expected. I logged in and saw the Customer and Employee info in my views.
I started seeing the error you received "EntityType 'CustomUserLogin' has no key defined. Define the key for this EntityType" when I added a many to many relation ship in the EmployeeProfile class to a Departments class. In my scenario an Employee can belong to 1 or many departments and a department can have many employees. My database changes were good and even the classes compiled just like you experienced, however once I ran the project, the website would error out.
Backing out my changes resolved the issue. Something in my classes was throwing off the validation of the model, so I'll need to approach the problem differently. So just like in my case, your poco classes may have an issue.
Remove your 'Property' class and references. Make the project work with the base essentials. Once you have it working, add the Property class back in with just the Id property.
Let me know if you still need help.
Place the base.OnModelCreating at the bottom:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<ApplicationUser>().ToTable("Users").HasKey<int>(u => u.Id);
modelBuilder.Entity<CustomUserRole>().ToTable("UserRoles").HasKey(ur => new { ur.RoleId, ur.UserId });
modelBuilder.Entity<CustomUserLogin>().ToTable("UserLogins").HasKey<int>(ul => ul.UserId);
modelBuilder.Entity<CustomUserClaim>().ToTable("UserClaims").HasKey<int>(uc => uc.Id);
modelBuilder.Entity<CustomRole>().ToTable("Roles").HasKey<int>(r => r.Id);
base.OnModelCreating(modelBuilder);
}

Entity framework issue- The principal end of this association must be explicitly configured

Hi I am using CodeFirst approach to create database but I am getting below error
The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.
The entities are following
public abstract class EntityBase
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public DateTime CreationDate { get; set; }
public DateTime ModifiedDate { get; set; }
public int CreatedByUserId { get; set; }
public int ModifiedByUserId { get; set; }
[ForeignKey("CreatedByUserId")]
public virtual User CreatedBy { get; set; }
[ForeignKey("ModifiedByUserId")]
public virtual User ModifiedBy { get; set; }
public bool IsActive { get; set; }
}
public class User : EntityBase
{
public string UserName { get; set; }
public string DisplayName { get; set; }
public string Password { get; set; }
}
Please help me.
Thanks
Vinod

updating an entity needs re-making relations in ef?

I am using ef 4.1 in my application and I have entities like below:
public partial class Role
{
[Key]
public int Id { get; set; }
[StringLength(20)]
[Required()]
public string RoleTitle { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public partial class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long UserId { get; set; }
[StringLength(20)]
[Required()]
public string UserName { get; set; }
public bool Status { get; set; }
[Required()]
public virtual Role Role { get; set; }
}
is it true that every time I want to update some field of User entity, say Status, I should re0make it is relations ?
Cause when I want to update only status field and save changes (I use Unit of Work), it throws and says "The Role field is required."...
No, you don't have to remake its relations. You also shouldn't be putting the Required annotation on the virtual property. You should be putting it on the ForeignKey ID field for the Role table. I believe you're getting the error because it's never setting the Role correctly on the User class in the first place, which is why you keep having to remake it.
To illustrate, here's what your User class should look like:
public partial class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public long UserId { get; set; }
[StringLength(20)]
[Required]
public string UserName { get; set; }
[Required, ForeignKey("Role")]
public int RoleID { get; set; }
public bool Status { get; set; }
public virtual Role Role { get; set; }
}

Multiplicity issue while mapping a table in Entity Framework

I currently have a class:
[Table("TitleCategoryMovie", Schema = "dbo")]
public class TitleCategoryMovie
{
[Key]
public int Id { get; set; }
public string CreatedBy { get; set; }
public DateTime CreateDatetime { get; set; }
public string UpdatedBy { get; set; }
public DateTime UpdateDatetime { get; set; }
[ForeignKey("Id")]
public virtual Title Title { get; set; }
}
There is a table called Title. And every TitleCategoryMovie has a corresponding Title, although not every Title has a TitleCategoryMovie. The column Id for Title is also the same for TitleCategoryMovie. But when I add both entity classes to my DbContext, it gives me an error:
Multiplicity is not valid in Role 'TitleCategoryMovieStandalone_Title_Source' in relationship 'TitleCategoryMovieStandalone_Title'. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be �1�.
I've already defined my column Id in TitleCategoryMovie as a primary key and a foreign key to Title, so I don't know why it's giving me this error. What's wrong?
You should also add a TitleId field and use that one as the parameter in the [ForeignKey] attribute:
[Table("TitleCategoryMovie", Schema = "dbo")]
public class TitleCategoryMovie
{
[Key]
public int Id { get; set; }
public string CreatedBy { get; set; }
public DateTime CreateDatetime { get; set; }
public string UpdatedBy { get; set; }
public DateTime UpdateDatetime { get; set; }
public int TitleId { get; set; }
[ForeignKey("TitleId")]
public virtual Title Title { get; set; }
}
Update after comments
I believe something like this should work:
[Table("TitleCategoryMovie", Schema = "dbo")]
public class TitleCategoryMovie
{
[Key]
public int Id { get; set; }
public string CreatedBy { get; set; }
public DateTime CreateDatetime { get; set; }
public string UpdatedBy { get; set; }
public DateTime UpdateDatetime { get; set; }
public virtual Title Title { get; set; }
}
[Table("Title", Schema = "dbo")]
public class Title
{
[Key]
[ForeignKey("TitleCategoryMovie")]
public int Id { get; set; }
public string Something { get; set; }
public virtual TitleCategoryMovie TitleCategoryMovie { get; set; }
}
You should put the [ForeignKey] attribute in the class that you consider to be the child of the relationship.
I was mapping two entities to one table. Apparently this isn't allowed in Entity Framework, so that was why I was getting that error.