MVC how to set Navigation Properties - c#

I am having issues with making the navigation properties correctly since I get the error
The Foreign key component ID is not a declared property on type Administrator.
My model basically consists of a base class User which has two derived classes Administrator and Common user. I believe this is a one to many relation since there can be multiple common and administrator users.
My classes look like this:
[Table("User")]
public class User
{
[Key]
public int ID { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public DateTime RegisterDate { get; set; }
public virtual ICollection<Common> CommonUsers { get; set; }
public virtual ICollection<Administrator> Administrators { get; set;}
}
public class Administrator : Usuario
{
[ForeignKey("User")]
public int ID { get; set; }
public virtual User User { get; set; }
}
public class Common : Usuario
{
[ForeignKey("User")]
public int ID { get; set; }
public virtual User User { get; set; }
}
I set the foiregn key on both ID attributes in the derived classes to reference the User ID which is the primary key for the table.
Any input would be appreciated.

Semantically your construction
public virtual ICollection<Common> CommonUsers { get; set; }
public virtual ICollection<Administrator> Administrators { get; set;}
mean that a single user can be multiple Administrators and each Administrator can be assigned to a single user.
public virtual User User { get; set; }
From the logic explained it should vise versa.
public class User
{
[Key]
public int ID { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public DateTime RegisterDate { get; set; }
//public virtual ICollection<Common> CommonUsers { get; set; }
public virtual Administrator Administrators { get; set;}
}
public class Administrator : Usuario
{
//Primary key is required but not defined
[ForeignKey("User")]
public int ID { get; set; }
//same admin role applies to many users
public virtual ICollection<User> User { get; set; }
}
Also note that class name User may shadow / conflict with System.Security.Principal.User
Most probably you mean
public class Usuario // User
{
[Key]
public int ID { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public DateTime RegisterDate { get; set; }
//public virtual ICollection<Common> CommonUsers { get; set; }
//public virtual ICollection<Administrator> Administrators { get; set;}
//define 1-to-1(0)
public virtual Common CommonUsers { get; set; }
public virtual Administrator Administrators { get; set;}
}
public class Administrator : Usuario
{
[ForeignKey("User")]
public int ID { get; set; }
public virtual User User { get; set; }
}

Related

Set two foreign keys with different names

I have an Offer entity that provides a link between two users in my system.
public class Offer
{
public OfferStatus Status { get; set; }
public decimal Amount {get; set; }
public virtual User Provider { get; set; }
public virtual User Receiver { get; set; }
}
This User entity has primary key of:
public string Id { get; set; }
I would like to have the two users ID strings appear in the Offer table like so:
public class Offer
{
public OfferStatus Status { get; set; }
public decimal Amount {get; set; }
public string ProviderId { get; set; }
public string ReceiverId { get; set; }
public virtual User Provider { get; set; }
public virtual User Receiver { get; set; }
}
I have tried:
public class Offer
{
public OfferStatus Status { get; set; }
public decimal Amount {get; set; }
public string ProviderId { get; set; }
public string ReceiverId { get; set; }
[ForeignKey(nameof(ProviderId))]
public virtual User Provider { get; set; }
[ForeignKey(nameof(ReceiverId))]
public virtual User Receiver { get; set; }
}
This is how I usually set foreign keys but usually I only have one of them and I use the naming convention magic that EF provides so I know what I have done here is wrong but I am confused how I am supposed to set their foreign key properties.

Entity Framework - Multiple navigation property

I started working with Entity Framework and I have one BIG problem. I want a many-to-many relation between entities User and Role.
So I created 3 tables User, Role, UserRoles
Next I created 3 entities:
public class User
{
public virtual int UserId { get; protected set; }
public virtual string UserName { get; set; }
public virtual string Password { get; set; }
public virtual DateTime CreateDate { get; set; }
public virtual ICollection<UserRole> Roles { get; set; }
public virtual ICollection<UserRole> CreatedRoles { get; set; }
}
public class Role
{
public virtual int RoleId { get; protected set; }
public virtual string Name { get; set; }
}
public class UserRole
{
public virtual int UserRoleId { get; protected set; }
public virtual int UserId { get; set; }
public virtual User User { get; set; }
public virtual int RoleId { get; set; }
public virtual Role Role { get; set; }
public virtual DateTime CreateDate { get; set; }
public virtual int CreateUserId { get; set; }
public virtual User CreateUser { get; set; }
}
I want to separate mapped user from created user. And In this step Entity Framework start to throw a bugs.
Next I want navigate from User object to his mapped roles and to his created mappings.
Can I configure Entity Framework to do these things?
You should apply InverseProperty attribute:
public class User
{
public virtual int UserId { get; protected set; }
public virtual string UserName { get; set; }
public virtual string Password { get; set; }
public virtual DateTime CreateDate { get; set; }
[InverseProperty("User")]
public virtual ICollection<UserRole> Roles { get; set; }
[InverseProperty("CreateUser")]
public virtual ICollection<UserRole> CreatedRoles { get; set; }
}

How to add a List of Users in a User Class using EF CodeFirst

I'm creating my DB using EF CodeFirst.
I have created the following User Class-
public class User
{
public User()
{
}
[Key]
public int ID { get; set; }
[Required, MinLength(4), MaxLength(20)]
public string Name { get; set; }
[Required, MinLength(8), MaxLength(40)]
public string Email { get; set; }
[Required, MinLength(8), MaxLength(15)]
public string Password { get; set; }
[Required]
public DateTime JoinedOn { get; set; }
public List<Users> Friends { get; set; } // Problem Adding List of Users in User Class
}
I want to store the List of friends for each user. And, I'm unable to add a Friends collection property to this User Class.
I have spent a lot of time trying this.
Is there any way to achieve the same?
The following code solved my problem-
public class User
{
public User()
{
Users = new List<User>();
Friends = new List<User>();
ChatRooms = new List<ChatRoom>();
}
[Key]
public int ID { get; set; }
[Required, MinLength(4), MaxLength(20)]
public string Name { get; set; }
[Required, MinLength(8), MaxLength(40)]
public string Email { get; set; }
[Required, MinLength(8), MaxLength(15)]
public string Password { get; set; }
[Required]
public DateTime JoinedOn { get; set; }
[InverseProperty("Friends")]
public virtual ICollection<User> Users { get; set; }
public virtual ICollection<User> Friends { get; set; }
[InverseProperty("Participants")]
public virtual ICollection<ChatRoom> ChatRooms { get; set; }
}
I just added-
[InverseProperty("Friends")]
public virtual ICollection<User> Users { get; set; }
public virtual ICollection<User> Friends { get; set; }
Thanks! Everyone...

Make a good relation between group, users with an owner with entity framework code first

I would try to make a relation between two entities : A goup (with an owner and users) and user (which belongs to a unique group). Code :
public class User
{
public int Id { get; set; }
public int GroupId { get; set; }
public virtual Group group { get; set; }
}
public class Group
{
public int Id { get; set; }
public User Owner { get; set; }
public virtual ICollection<User> Users { get; set; }
}
I don't arrive with data annotation to make it corectly.
Thank you so much for your propositions
A solution that works for me :
public class User
{
public int Id { get; set; }
public int? GroupId { get; set; }
[InverseProperty("Users")]
public virtual Group group { get; set; }
}
public class Group
{
public int Id { get; set; }
public int? OwnerId { get; set; }
public User Owner { get; set; }
public virtual ICollection<User> Users { get; set; }
}

EF 4: System.Data.Entity.Edm.EdmEntityType: Name: Each type name in a schema must be unique

I want to use EF code first approach.
I have read this post:
http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx
and created my BL classes
public class AppData
{
public string Id { get; set; }
public string Url { get; set; }
public AppData_OptionsDialog OptionsDialog { get; set; }
public AppData_Compatibility Compatibility { get; set; }
}
public class AppData_Compatibility
{
public int Id { get; set; }
public string Platform { get; set; }
public string MaxVersion { get; set; }
}
public class AppData_OptionsDialog
{
public int Id { get; set; }
public string DisplayName { get; set; }
public string AppDesc { get; set; }
public string PrivacyPolicyUrl { get; set; }
public string TermsOfUseUrl { get; set; }
}
public class AppsDataContext : System.Data.Entity.DbContext
{
public AppsDataContext() : base("MaMDB") { }
public DbSet<Conduit.Mam.Common.BlData.AppsData.AppData> AppsData { get; set; }
public DbSet<Conduit.Mam.Common.BlData.AppsData.AppData_Compatibility> AppData_Compatibilities { get; set; }
public DbSet<Conduit.Mam.Common.BlData.AppsData.AppData_OptionsDialog> AppData_OptionsDialogs { get; set; }
}
I have created corrisponding tables in the DB.
I understand EF uses convention over configuration.
So is it magically maps the classes to the DB? no need to generate an em
I try to execute a test on of the methods:
public IList<Conduit.Mam.Common.BlData.AppsData.AppData> GetAll()
{
var apps = from app in AppsDataContext.AppsData
select app;
return apps.ToList();
}
but get the following error:
One or more validation errors were detected during model generation:
\tSystem.Data.Entity.Edm.EdmEntityType: Name: Each type name in a
schema must be unique. Type name 'AppData_OptionsDialog' is already
defined. \tSystem.Data.Entity.Edm.EdmEntityType: Name: Each type name
in a schema must be unique. Type name 'AppData_Compatibility' is
already defined.
I have seen this answer, but it didn't help me
Entity Framework error - "The EntityContainer name must be unique"
I think I know what the problem is, even though this is incredibly old, I'm running across the same problem now, it seems EF doesn't like it when you have:
public class User_Roles {
public bool Admin { get; set; }
public bool Moderator { get; set; }
public virtual User User { get; set; }
}
public class User {
public Guid Id { get; set; }
public string Username { get; set; }
public string Salt { get; set; }
public string Password { get; set; }
public virtual User_Roles Roles { get; set; }
}
In this case, either User_Roles needs to be renamed or the Roles property in User needs to be renamed, as so:
public class URoles {
public bool Admin { get; set; }
public bool Moderator { get; set; }
public virtual User User { get; set; }
}
public class User {
public Guid Id { get; set; }
public string Username { get; set; }
public string Salt { get; set; }
public string Password { get; set; }
public virtual URoles Roles { get; set; }
}
or you could simply change the "Roles" property in User:
public class User_Roles {
public bool Admin { get; set; }
public bool Moderator { get; set; }
public virtual User User { get; set; }
}
public class User {
public Guid Id { get; set; }
public string Username { get; set; }
public string Salt { get; set; }
public string Password { get; set; }
public virtual User_Roles URoles { get; set; }
}
in your case, this is happening on:
public AppData_OptionsDialog OptionsDialog { get; set; }
public AppData_Compatibility Compatibility { get; set; }
Either rename the class, or rename the properties.

Categories

Resources