0

I have two classes and their relations are as below:

public class InteractiveObject
{
     public int Id {get; set;}
     public string Name{ get; set; }

     public int? IndicatorId { get; set; }
     public virtual Indicator Indicator { get; set; }
}

public class Indicator
{
     public int Id {get; set;}
     public string Name{ get; set; }

     public int InteractiveObjectId { get; set; }
     public virtual InteractiveObject InteractiveObject { get; set; }
}

And I configure it like

  modelBuilder.Entity<Indicator>().HasRequired(x => x.InteractiveObject)
            .WithOptional(x => x.Indicator);

It creates two tables that the table Indicator has not a nullable InteractiveObjectId, and table InteractiveObject has a nullable IndicatorId. Perfect.

But when I try to add Indicator with an InteractiveObject. The table Indicator contains the all information but the related InteractiveObject table does not contain IndicatorId. I mean IndicatorId is null on InteractiveObject table but InteractiveObjectId is not null on Indicator table

The code is like below:

  modelBuilder.Entity<Indicator>().HasRequired(x => x.InteractiveObject)
            .WithOptional(x => x.Indicator);

        var selectedInteractiveObject = DbContext.Set<InteractiveObject>().FirstOrDefault(x => x.Id == 1);

        var indicator = new Indicator { Name = "Test"};

        selectedInteractiveObject.Indicator = indicator;

        DbContext.SaveChanges();
3
  • What is primary key in both the entities? Commented Apr 10, 2015 at 6:52
  • @JenishRabadiya I have forgotten it while minimizing the code. I edit it now Commented Apr 10, 2015 at 6:54
  • By default EF will create foreign keys as Entity_Id. So in your case InteractiveObjectId_Id. Did you check if your tables have foreign keys with underscores instead of the expected InteractiveObjectId? Commented Apr 10, 2015 at 7:01

2 Answers 2

1

Since we have one-to-zero or one relation we don't need to define separate keys as they can share same Id, but Indicator refers to InteractiveObject. That means that InteractiveObject can exist w/o Indicator but not vice versa.

So class objects should be like this:

 public class Indicator
    {
        [ForeignKey("InteractiveObject")]
        public int Id { get; set; }

        public string Name { get; set; }

        public virtual InteractiveObject InteractiveObject { get; set; }
    }

    public class InteractiveObject
    {

        public int Id { get; set; }

        public string Name { get; set; }

        public virtual Indicator Indicator { get; set; }
    }

You should have your context class inherited from DbContext like this:

public partial class YourContext: DbContext
    {
        static YourContext() { }

        //Class constructor with Connection String name
        public YourContext() : base("name=YourConnectionString") { }

        public DbSet<Indicator> Indicators{ get; set; }
        public DbSet<InteractiveObject> InteractiveObjects { get; set; }
}

And now you can operate on its instance via disposable pattern:

using (var context = new YourContext())
{
    var selectedInteractiveObject = context.InteractiveObjects.FirstOrDefault(x => x.Id == 1);
    var indicator = new Indicator { Name = "Test" };
    selectedInteractiveObject.Indicator = indicator;
    context.SaveChanges();
}
Sign up to request clarification or add additional context in comments.

4 Comments

When I leave it as it owns, it gives me an error like
The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.
Sorry, I misled you a bit. Since we have one-to-zero or one relation we don't need to define separate keys as they can share single Id. So I've updeted my answer.
0

well, You are looking for the value in wrong column.

If you have applied -Versbose flag while running migration you would have noticed following SQL statement creating foreign key constraint.

ALTER TABLE [dbo].[Indicators] ADD CONSTRAINT [FK_dbo.Indicators_dbo.InteractiveObjects_Id] FOREIGN KEY ([Id]) REFERENCES [dbo].[InteractiveObjects] ([Id])

Id column of Indicator is the foreign key so it would have value pointing to the ID of InteractiveObject.

Update

Making the Id of Indicator as foreign key also force the constraint that it is one to one or zero relationship while if IndicatorId in InteractiveObject would be the foreign key it appeared to be one to zero or many relationship.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.