我在弄清楚为什么可以使用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
答案 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();
“来宾”与您的“上下文”实例的工作上下文无关,因此来宾永不保存。我希望你能明白。