1
votes

I need 1:1 relationship between ApplicationUser and my own class in entity framework.

I do this:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }

    /*Realations*/

    public virtual ICollection<Comment> Comments { get; set; }
    public virtual Posts Post { get; set; }
}


public class Posts : System.Object
{
    public Posts()
    {
        this.PostDate = DateTime.Now;
        this.PostViews = 0;
        this.PostPic = "d.jpg";
    }

    [Key]
    public int PostID { get; set; }

    public string PostName { get; set; }
    public string PostSummery { get; set; }
    public string PostDesc { get; set; }
    public string PostPic { get; set; }
    public DateTime PostDate { get; set; }
    public int PostViews { get; set; }
    public string postMetaKeys { get; set; }
    public string PostMetaDesc { get; set; }


    public string UserId { get; set; }
    [Key, ForeignKey("UserId")]
    public virtual ApplicationUser ApplicationUser { get; set; }


    public int CategoryID { get; set; }
    [Key, ForeignKey("CategoryID")]
    public virtual Categories Category { get; set; }

    public virtual ICollection<Comment> commnets {get; set;}
}

But I am getting an exception when I write the command "add-migration relation" inside Nuget console.

Unable to determine the principal end of an association between the types 'FinalKaminet.Models.ApplicationUser' and 'Models.Posts'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

I also add below code inside IdentityModels, but another error was shown:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder); 


        modelBuilder.Entity<ApplicationUser>()
        .HasOptional(f => f.Post)
        .WithRequired(s => s.ApplicationUser);
    }

One or more validation errors were detected during model generation:

ApplicationUser_Post_Target: : Multiplicity is not valid in Role 'ApplicationUser_Post_Target' in relationship 'ApplicationUser_Post'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

What is wrong?

2
what is shown another error?Adil Mammadov
@AdilMammadov, Updated question.Farzaneh Talebi
As I remember IdentityUser has string key. Can it be the problem?Adil Mammadov
I declare the FK as string,too. public string UserId { get; set; }Farzaneh Talebi
where do you need to create 1:1 relationship ? ApplicationUser : Posts ? why you have used wrong naming for the Post ? class name should be the singular.collections should be plural. like this ` public virtual Post Posts { get; set; }`.but that thing is just a side note.note related to your issue.hope you'll give a feedback for this.Sampath

2 Answers

1
votes

you want a 1 to 1 relation between user and post ? A user can only post one, and only, post ?

Anyway, in EF (at least 6) a 1 to 1 relation can be established between two entities sharing the same PK. That is the PK is the FK. So you must set the PK of posts as a string.

Otherwise you are in a 1 to * relation.

0
votes

Add [Required] attribute to UserId property in Posts class.

By default, a string property would be nullable but as this is the foreign key and you want the relationship to be Required, you'll have to set the UserId property as not-nullable which can be done by adding [Required] attribute.