Hidden
Hidden

Reputation: 7482

Entity Framework One to one property not saving

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

Answers (3)

chandrakant
chandrakant

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

Steve Py
Steve Py

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

Dharmeshsharma
Dharmeshsharma

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

Related Questions