Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating 2 Relationships Between Two Entities Using Entity Framework Code First

I'm trying to define a one to many relationship, as well as a one to one relationship between the same 2 entities "UserProfile" and "Blog". I think I have succeeded with the following code, however, it results in creating a new column in "Blog" table called "UserProfile_UserId" (FK). I don't understand why it does this.

The relationships in English are: 1. "A UserProfile has many Blogs" 2. "A UserProfile has one main optional (nullable) Blog"

So ultimately I'd like to see a FK from Blog.UserId to UserProfile.UserId And a nullable FK from UserProfile.BlogId to Blog.Id And I think that is all... I especially don't want additional columns added by EF.

public class UserProfile
{
    [Key]
    public int UserId { get; set; }
    public int? BlogId { get; set; }
    public virtual Blog Blog { get; set; }  // This is a user's main blog
    public virtual ICollection<Blog> AllUsersBlogs { get; set; }
}

public abstract class Blog
{
    [Key]
    public int Id { get; set; }


    public int UserId { get; set; }

    [ForeignKey("UserId")]
    public virtual UserProfile User { get; set; }
}
like image 572
JayPrime2012 Avatar asked May 31 '26 08:05

JayPrime2012


1 Answers

That's pretty tricky thing to make - by default CF puts all the relationships / FK-s on one side. And that's for a reason, because it simplifies things, avoid cyclical references and contradicting 'constraints' on two sides

what often happens is the error reporting that from one FK ir requires to be of multiplicity '1' and from the other FK it has to be * - resulting in an exception.

But this works all you want I think - you just have to 'feed it' the data carefully...

public class UserProfile
{
    [Key]
    public int UserId { get; set; }
    [ForeignKey("Blog")]
    public int? BlogId { get; set; }
    public virtual Blog Blog { get; set; }  // This is a user's main blog
    public virtual ICollection<Blog> AllUsersBlogs { get; set; }
}

//abstract 
public class Blog
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("User")]
    public int UserId { get; set; }

    // [ForeignKey("UserId")]
    public virtual UserProfile User { get; set; }
}

In your fluent config...

modelBuilder.Entity<Blog>()
    .HasRequired(x => x.User)
    .WithMany(x => x.AllUsersBlogs)
    .HasForeignKey(x => x.UserId)
    .WillCascadeOnDelete(false);

And use it like this...

var user = db.UserProfiles.Add(new UserProfile
{
    //Blog = mainblog,
    AllUsersBlogs = new List<Blog>
    {
        new Blog{},
        new Blog{},
        new Blog{},
        new Blog{},
        new Blog{},
    }
});
db.SaveChanges();
var mainblog = new Blog { User = user, };
user.Blog = mainblog;
db.SaveChanges();

Note that for the main blog - you have to explicitly specify the User for your blog now - plus set it as the user's main blog.

That's because you have two different relationships now - one is mandatory (User in the Blog) - and another is the optional main blog.

Anyhow, if this doesn't satisfy your demands (though it looks it should I think) - then I'd suggest that you let it create things by default and have FK-s on the Blog side, you lose the BlogId but it simplifies things a lot.

like image 187
NSGaga-mostly-inactive Avatar answered Jun 02 '26 21:06

NSGaga-mostly-inactive



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!