实体框架一对一属性未保存

时间:2019-11-13 04:50:43

标签: c# entity-framework

我在弄清楚为什么可以使用ontext.CommunicationPreferences.Add直接保存到集合中时遇到麻烦。但是尝试添加到guest.communicationPreference中是行不通的。

我在某处缺少某些映射吗?谢谢!

代码

    [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);
        }
    }

数据库

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

3 个答案:

答案 0 :(得分:2)

您正在4个不同的上下文实例中加载数据。...

此:

    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();
    }

将所有内容都放在同一上下文中,因为上下文4(using一个)不了解上下文1(来宾)中的实体

这将起作用:

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();
}

答案 1 :(得分:1)

除了为什么不更新之外,我忽略了其他所有方面。

通过add()添加实体时,它将实体的状态设置为自动修改,但是如果您不使用add(),则 您需要手动修改实体状态。

context.Entry(guest.CommunicationPreference).State = EntityState.Modified;

您需要在保存更改之前添加以上行。

答案 2 :(得分:0)

在此代码块中

  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(); 

“来宾”与您的“上下文”实例的工作上下文无关,因此来宾永不保存。我希望你能明白。