locked
EF 4.2 Code First - setting 2 relationships between 2 entities RRS feed

  • Question

  • Hi all,
    I'm having troubles on creating two (1 to many) relations between 2 entities.
    I'm using EF 4.2 Code First with Sql Compact 4.0. Here are the Classes:

      [Table("Details")]
      public class Detail
      {
        [Key]
        [Column("rid")]
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
        public long rid { get; set; }
    
        [Required]
        public string DummyPropDetail { get; set; }
    
    
        [Column(name: "ridMaster1")]
        public long ridMaster1 { get; set; }
    
        [ForeignKey("ridMaster1")]
        public virtual Master Master1 { set; get; }
    
    
    
        [Column(name: "ridMaster2")]
        public long ridMaster2 { get; set; }
    
        [ForeignKey("ridMaster2")]
        public virtual Master Master2 { set; get; }
    
      }
    
    

     

      [Table("Masters")]
      public class Master
      {
        [Key]
        [Column("rid")]
        [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
        public long rid { get; set; }
    
    
    
        [Required]
        public string DummyPropMaster { get; set; }
    
    
        [InverseProperty("Master1")]
        public ICollection<Detail> Details1 { get; set; }
    
    
        [InverseProperty("Master2")]
        public ICollection<Detail> Details2 { get; set; }
    
      }
    


    When creating the database I got the exception (I'm translating in english from my localized VS version):

    "The referential relationship involves the creation of a cyclical reference that is not allowed (contraint Name: Master_Detail2)".

    If I create the two Foreign Keys as nullable :

    public long? ridMaster1 { get; set; }
    public long? ridMaster2 { get; set; }

    I don't get the exception but  I need to have the foreign keys required, I mean: a Details MUST have all the two Masters setted.

    How can I create Non-nullable Foreign Keys / Navigation Property?

    Thanks

    Franco

     

     

     

     

     

    Thursday, September 1, 2011 10:10 AM

Answers

  • Hi Franco,

    Welcome!

    Please feel free to test my code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity;
    
    namespace ConsoleApplication64
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var context= new MyContext())
                {
                    context.Database.CreateIfNotExists();
                }
            }
        }
        [Table("Details")]
        public class Detail
        {
            [Key]
            [Column("rid")]
            [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
            public long rid { get; set; }
            [Required]
            public string DummyPropDetail { get; set; }
            [Column(name: "ridMaster1")]
            public long ridMaster1 { get; set; }
    
            [ForeignKey("ridMaster1")]
            public virtual Master Master1 { set; get; }
            [Column(name: "ridMaster2")]
            public long ridMaster2 { get; set; }
    
            [ForeignKey("ridMaster2")]
            public virtual Master Master2 { set; get; }
        }
        [Table("Masters")]
        public class Master
        {
            [Key]
            [Column("rid")]
            [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
            public long rid { get; set; }
            [Required]
            public string DummyPropMaster { get; set; }
            [InverseProperty("Master1")]
            public ICollection<Detail> Details1 { get; set; }
            [InverseProperty("Master2")]
            public ICollection<Detail> Details2 { get; set; }
        }
        public class MyContext:DbContext
        {
            public DbSet<Detail> Details { get; set; }
            public DbSet<Master> Masters { get; set; }
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Detail>().HasRequired(d => d.Master1).WithMany(m => m.Details1).HasForeignKey(d=>d.ridMaster1).WillCascadeOnDelete(false);
                modelBuilder.Entity<Detail>().HasRequired(d => d.Master2).WithMany(m => m.Details2).HasForeignKey(d => d.ridMaster2).WillCascadeOnDelete(false);
            }
        }
    }
    

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by FraCal Wednesday, September 7, 2011 7:10 AM
    Friday, September 2, 2011 7:17 AM

All replies

  • Hi Franco,

    Welcome!

    Please feel free to test my code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity;
    
    namespace ConsoleApplication64
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (var context= new MyContext())
                {
                    context.Database.CreateIfNotExists();
                }
            }
        }
        [Table("Details")]
        public class Detail
        {
            [Key]
            [Column("rid")]
            [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
            public long rid { get; set; }
            [Required]
            public string DummyPropDetail { get; set; }
            [Column(name: "ridMaster1")]
            public long ridMaster1 { get; set; }
    
            [ForeignKey("ridMaster1")]
            public virtual Master Master1 { set; get; }
            [Column(name: "ridMaster2")]
            public long ridMaster2 { get; set; }
    
            [ForeignKey("ridMaster2")]
            public virtual Master Master2 { set; get; }
        }
        [Table("Masters")]
        public class Master
        {
            [Key]
            [Column("rid")]
            [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
            public long rid { get; set; }
            [Required]
            public string DummyPropMaster { get; set; }
            [InverseProperty("Master1")]
            public ICollection<Detail> Details1 { get; set; }
            [InverseProperty("Master2")]
            public ICollection<Detail> Details2 { get; set; }
        }
        public class MyContext:DbContext
        {
            public DbSet<Detail> Details { get; set; }
            public DbSet<Master> Masters { get; set; }
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Detail>().HasRequired(d => d.Master1).WithMany(m => m.Details1).HasForeignKey(d=>d.ridMaster1).WillCascadeOnDelete(false);
                modelBuilder.Entity<Detail>().HasRequired(d => d.Master2).WithMany(m => m.Details2).HasForeignKey(d => d.ridMaster2).WillCascadeOnDelete(false);
            }
        }
    }
    

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by FraCal Wednesday, September 7, 2011 7:10 AM
    Friday, September 2, 2011 7:17 AM
  • Hi Alan,
    is there a way to have that using DataAnnotations?
    It seems that ForeignKeyAttribute & InverseProperty do not work in this case, or is by design?
    I would like to implement this via DataAnnotations becouse the classes will be used in many context and the Fluent Api code must be repeated for every context.

    Thanks

     

     

    Monday, September 5, 2011 7:21 AM
  • Hi FraCal,

    Thanks for your feedback.

    I'm afraid you should use Fluent API in your scenario.

    The more information is here: http://weblogs.asp.net/manavi/archive/2011/01/23/associations-in-ef-code-first-ctp5-part-3-one-to-one-foreign-key-associations.aspx

    http://stackoverflow.com/questions/5828394/entity-framework-4-1-inverseproperty-attribute-and-foreignkey

    Thanks for understanding.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, September 6, 2011 1:04 PM