首页 > 解决方案 > 实体框架一对一属性不保存

问题描述

我很难弄清楚为什么我可以使用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

标签: c#entity-framework

解决方案


您正在将数据加载到 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();
}

推荐阅读