Reputation: 7482
I'm having troubles figuring out why I can save directly to the collection with ontext.CommunicationPreferences.Add
. But Trying to add to guest.communicationPreference
does not work.
Am I missing some mapping somewhere? Thanks!
Code
[TestMethod]
public void TestMethod1()
{
var guests = new Context().Guests.ToList();
var communicationTypes = new Context().CommunicationTypes.ToList();
var communicationPreferences = new Context().CommunicationPreferences.ToList();
using (var context = new Context())
{
var guest = guests.FirstOrDefault(x => x.Id == 1);
// This works
context.CommunicationPreferences.Add(new CommunicationPreference(1, guest.Id, communicationTypes.First().Id));
// This does not work - why? :(
guest.CommunicationPreference = new CommunicationPreference(1, guest.Id, communicationTypes.First().Id);
context.SaveChanges();
}
}
public class CommunicationPreference
{
public CommunicationPreference()
{
}
public CommunicationPreference(int time, int guestId, int communicationTypeId)
{
Time = time;
GuestId = guestId;
CommunicationTypeId = communicationTypeId;
}
public int GuestId { get; set; }
public int? CommunicationTypeId { get; set; }
public virtual CommunicationType CommunicationType { get; set; }
public virtual Guest Guest { get; set; }
public int? Time { get; set; }
}
public class CommunicationType
{
public CommunicationType()
{
}
public int Id { get; set; }
public string Name { get; set; }
}
public class Guest
{
public Guest()
{
}
public int Id { get; set; }
public string FirstName { get; set; }
public virtual CommunicationPreference CommunicationPreference { get; set; }
}
public class Context : DbContext
{
public Context() : base("Context")
{
}
public DbSet<Models.Guest> Guests { get; set; }
public DbSet<Models.CommunicationType> CommunicationTypes { get; set; }
public DbSet<Models.CommunicationPreference> CommunicationPreferences { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
this.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
modelBuilder.Entity<Models.CommunicationPreference>().HasKey(t => t.GuestId);
modelBuilder
.Entity<Models.CommunicationPreference>()
.HasRequired<Models.Guest>(x => x.Guest)
.WithOptional(x => x.CommunicationPreference);
}
}
Database
CREATE TABLE [dbo].[Guest](
[Id] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [varchar](50) NOT NULL,
CONSTRAINT [PK_Guest] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[CommunicationType](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
CONSTRAINT [PK_CommunicationType] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[CommunicationPreference](
[Time] [int] NULL,
[CommunicationTypeId] [int] NULL,
[GuestId] [int] NOT NULL,
CONSTRAINT [PK_CommunicationPreference] PRIMARY KEY CLUSTERED
(
[GuestId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[CommunicationPreference] WITH CHECK ADD CONSTRAINT [FK_CommunicationPreference_CommunicationType] FOREIGN KEY([CommunicationTypeId])
REFERENCES [dbo].[CommunicationType] ([Id])
GO
ALTER TABLE [dbo].[CommunicationPreference] CHECK CONSTRAINT [FK_CommunicationPreference_CommunicationType]
GO
ALTER TABLE [dbo].[CommunicationPreference] WITH CHECK ADD CONSTRAINT [FK_CommunicationPreference_Guest] FOREIGN KEY([GuestId])
REFERENCES [dbo].[Guest] ([Id])
GO
ALTER TABLE [dbo].[CommunicationPreference] CHECK CONSTRAINT [FK_CommunicationPreference_Guest]
GO
Upvotes: 0
Views: 134
Reputation: 79
I am ignoring every other aspects except why not updating.
When you adding entity by add() it set state of the that entity to modified automatically but if you not using add() then You need to modify your state of entity manually.
context.Entry(guest.CommunicationPreference).State = EntityState.Modified;
You need to add above line before saving changes.
Upvotes: 1
Reputation: 34653
You are loading your data in 4 different context instances....
This:
var guests = new Context().Guests.ToList(); // Context 1
var communicationTypes = new Context().CommunicationTypes.ToList(); // Context 2
var communicationPreferences = new Context().CommunicationPreferences.ToList(); // Context 3
using (var context = new Context()) // Context 4
{
var guest = guests.FirstOrDefault(x => x.Id == 1);
// This works
context.CommunicationPreferences.Add(new CommunicationPreference(1, guest.Id, communicationTypes.First().Id));
// This does not work - why? :(
guest.CommunicationPreference = new CommunicationPreference(1, guest.Id, communicationTypes.First().Id);
context.SaveChanges();
}
Put everything in the same context because Context #4 (using
one) doesn't know about entities from Context 1 (guests)
This would work:
using (var context = new Context())
{
var guests = context.Guests.ToList();
var communicationTypes = context.CommunicationTypes.ToList();
var communicationPreferences = context.CommunicationPreferences.ToList();
var guest = guests.FirstOrDefault(x => x.Id == 1);
guest.CommunicationPreference = new CommunicationPreference(1, guest.Id, communicationTypes.First().Id);
context.SaveChanges();
}
Upvotes: 2
Reputation: 691
in this block of code
context.CommunicationPreferences.Add(new CommunicationPreference(1, guest.Id, communicationTypes.First().Id));
// This does not work - why? :(
guest.CommunicationPreference = new CommunicationPreference(1, guest.Id, communicationTypes.First().Id);
context.SaveChanges();
The "guest" is not relate or not in work context of your "Context" instance so guest never save. I hope you get it.
Upvotes: 0