locked
EF Features CTP 5 - Foreign Key Associations RRS feed

  • Question

  • Assuming we are using EF Features CTP5 Code Only and we have the following entity:

    public class Unicorn
    {
      public int Id { get; set; }
      public string Name { get; set; }
    
      public int PrincessId { get; set; } // FK for Princess reference
      public virtual Princess Princess { get; set; }
    }
    

    Say we set the Unicorn.Princess navigation property of a Unicorn instance to a valid Princess instance:

    myUnicorn.Princess = ctx.Princesses.Find(1);
    // myUnicorn.PrincessId == 0
    

    We then observe that myUnicorn.PrincessId is still 0 (zero).

    Is there a way for the foreign key property to be kept in-sync with the navigation property? I have not found any built-in functionality for this. Obviously this behaviour could be coded into a Unicorn.AssignPrincess(...) instance method on the model but this seems like quite a common requirement?

    Friday, February 4, 2011 2:07 PM

Answers

  • To enable the FK fixup you need to add your new entity to the context

      class Program
      {
        static void Main(string[] args)
        {
          DbDatabase.SetInitializer(new UnicornsContextInitializer());
    
          using (var ctx = new UnicornsContext())
          {
            var myUnicorn = new Unicorn();
            myUnicorn.Princess = ctx.Princesses.Find(1);
            ctx.Unicorns.Add(myUnicorn);
    
            Console.WriteLine(myUnicorn.PrincessId); // 1
          }
        }
      }
    
      public class Unicorn
      {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public int PrincessId { get; set; } // FK for Princess reference
        public virtual Princess Princess { get; set; }
      }
    
      public class Princess
      {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public virtual ICollection<Unicorn> Unicorns { get; set; }
      }
    
      public class UnicornsContext : DbContext
      {
        public DbSet<Unicorn> Unicorns { get; set; }
        public DbSet<Princess> Princesses { get; set; }
      }
    
      public class UnicornsContextInitializer
      : DropCreateDatabaseAlways<UnicornsContext>
      {
        protected override void Seed(UnicornsContext context)
        {
          context.Princesses.Add(new Princess { Name = "Cinderella" });
        }
      }
    

     

    • Proposed as answer by Andriy Svyryd Friday, February 4, 2011 9:44 PM
    • Marked as answer by Matt___B Monday, February 7, 2011 8:51 AM
    Friday, February 4, 2011 9:44 PM

All replies

  • Tagging along for ride...
    Javaman, Cowboy Coders Unite!
    Friday, February 4, 2011 2:18 PM
  • To enable the FK fixup you need to add your new entity to the context

      class Program
      {
        static void Main(string[] args)
        {
          DbDatabase.SetInitializer(new UnicornsContextInitializer());
    
          using (var ctx = new UnicornsContext())
          {
            var myUnicorn = new Unicorn();
            myUnicorn.Princess = ctx.Princesses.Find(1);
            ctx.Unicorns.Add(myUnicorn);
    
            Console.WriteLine(myUnicorn.PrincessId); // 1
          }
        }
      }
    
      public class Unicorn
      {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public int PrincessId { get; set; } // FK for Princess reference
        public virtual Princess Princess { get; set; }
      }
    
      public class Princess
      {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public virtual ICollection<Unicorn> Unicorns { get; set; }
      }
    
      public class UnicornsContext : DbContext
      {
        public DbSet<Unicorn> Unicorns { get; set; }
        public DbSet<Princess> Princesses { get; set; }
      }
    
      public class UnicornsContextInitializer
      : DropCreateDatabaseAlways<UnicornsContext>
      {
        protected override void Seed(UnicornsContext context)
        {
          context.Princesses.Add(new Princess { Name = "Cinderella" });
        }
      }
    

     

    • Proposed as answer by Andriy Svyryd Friday, February 4, 2011 9:44 PM
    • Marked as answer by Matt___B Monday, February 7, 2011 8:51 AM
    Friday, February 4, 2011 9:44 PM
  • Thanks - I can see now that the FK property will be updated after certain methods are called, as described in the article below.

    http://blogs.msdn.com/b/adonet/archive/2011/02/06/using-dbcontext-in-ef-feature-ctp5-part-12-automatically-detecting-changes.aspx

    Monday, February 7, 2011 8:51 AM
  • Hi All,

    Thanks for all your participate and selfness sharing.

    Have a good day.



    David Peng [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.

    Monday, February 7, 2011 9:00 AM
  • If you assign the "Princess" with other ID after adding new "Unicorn", the ID will be still 0:

    using (var ctx = new UnicornsContext())
    {
       var myUnicorn = new Unicorn();
    
       ctx.Unicorns.Add(myUnicorn);
    
       // ...
    
       myUnicorn.Princess = ctx.Princesses.Find(3);
        
       // myUnicorn.PrincessId is not the correct ID
       Console.WriteLine(myUnicorn.PrincessId); // still 0
    }
    
    
    
    Friday, February 25, 2011 7:46 AM