Reputation: 5817
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();
Upvotes: 0
Views: 112
Reputation: 1315
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();
}
Upvotes: 1
Reputation: 6766
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.
Upvotes: 0