[英]EF One-to-One Update fails
I have one-to-one relationship defined in EF6 which works for Inserts. 我在EF6中定义了一对一关系,适用于插入。 Unfortunately when I try an update with a disconnected record, I receive an error.
不幸的是,当我尝试使用断开记录的更新时,收到错误消息。 Here are details:
详情如下:
.NET Source: .NET来源:
namespace EF_ConsoleApp_Test
{
public class Program
{
public static void Main(string[] args)
{
int? accountId;
int? customerId;
using (var db = new MainContext())
{
var account = new Account
{
AccountNumber = "1234",
Customer = new Customer {FirstName = "John"}
};
db.Accounts.Add(account);
db.SaveChanges();
accountId = account.Id;
customerId = account.Customer.Id;
}
using (var db = new MainContext())
{
// disconnected record
var account = new Account()
{
Id = accountId,
AccountNumber = "9876",
Customer = new Customer() {Id = customerId}
};
db.Accounts.Add(account);
db.Entry(account).State = EntityState.Modified;
db.Entry(account.Customer).State = EntityState.Unchanged;
db.SaveChanges(); // Error occurs here
}
}
[Serializable]
[Table("CUSTOMERS")]
public class Customer
{
[Key] [Column("CUSTOMER_ID")] public int? Id { get; set; }
[Required]
[Column("FIRST_NAME")]
[StringLength(45)]
public string FirstName { get; set; }
public virtual Account Account { get; set; }
public Customer() { }
}
[Serializable]
[Table("ACCOUNTS")]
public class Account
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
[Column("ACCOUNT_ID")]
public int? Id { get; set; }
[Required]
[Column("ACCOUNT_NUMBER")]
[Display(Name = "Account Number")]
[StringLength(16)]
public string AccountNumber { get; set; }
public virtual Customer Customer { get; set; }
/// <summary>
/// Default Constructor
/// </summary>
public Account() { }
}
internal class MainContext : DbContext
{
internal MainContext() : base("name=ACHRE.Context")
{
Database.SetInitializer<MainContext>(null);
}
public virtual DbSet<Account> Accounts { get; set; }
public virtual DbSet<Customer> Customers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure FK
modelBuilder.Entity<Customer>()
.HasRequired(c => c.Account)
.WithRequiredPrincipal(a => a.Customer)
.Map(m => m.MapKey("CUSTOMER_ID"));
base.OnModelCreating(modelBuilder);
}
}
}
}
Database Table Create statements: 数据库表创建语句:
CREATE TABLE [dbo].[CUSTOMERS](
[CUSTOMER_ID] [INT] IDENTITY(1,1) NOT NULL,
[FIRST_NAME] [varchar](45) NOT NULL,
CONSTRAINT [PK_CUSTOMERS] PRIMARY KEY CLUSTERED
(
[CUSTOMER_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].[ACCOUNTS](
[ACCOUNT_ID] [INT] IDENTITY(1,1) NOT NULL,
[CUSTOMER_ID] [int] NOT NULL,
[ACCOUNT_NUMBER] [varchar](16) NOT NULL,
CONSTRAINT [PK_ACCOUNTS] PRIMARY KEY CLUSTERED
(
[ACCOUNT_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]
ALTER TABLE [dbo].[ACCOUNTS] WITH CHECK ADD CONSTRAINT [FK_ACCOUNTS_CUSTOMERS] FOREIGN KEY([CUSTOMER_ID])
REFERENCES [dbo].[CUSTOMERS] ([CUSTOMER_ID])
GO
Error: 错误:
A relationship from the 'Customer_Account' AssociationSet is in the 'Added' state.
“ Customer_Account” AssociationSet中的关系处于“已添加”状态。 Given multiplicity constraints, a corresponding 'Customer_Account_Target' must also in the 'Added' state.
给定多重性约束,相应的“ Customer_Account_Target”也必须处于“已添加”状态。
What do I need to update to make this work? 我需要更新什么才能使其正常工作?
Notes 笔记
This is because you are adding the entity again. 这是因为您要再次添加实体。 You need to attach the object first by calling
db.Accounts.Attach(account);
您需要先通过调用
db.Accounts.Attach(account);
来附加对象db.Accounts.Attach(account);
. 。
Or a better approach would be to first fetch based on Id and then modify the desired fields like this : 或更好的方法是先基于Id取回,然后像这样修改所需的字段:
using (var db = new MainContext())
{
var account = db.Accounts.SingleOrDefault(x => x.id == accountId);
account.AccountNumber = "9876"
db.SaveChanges();
}
This is a side effect of the db.Accounts.Add(account);
这是
db.Accounts.Add(account);
的db.Accounts.Add(account);
call. 呼叫。 It sets some shadow state to
Added
which cannot be negated by the next State
manipulations. 它将某些阴影状态设置为“已
Added
,而下一个“ State
操作无法对其进行否定。
Attach
in advance doesn't work in this case. 在这种情况下,预先
Attach
无效。 So either use the second suggestion by @Harsh, or if you want to do forced update, don't call Add
but simply set the State
of the account
to Modified
. 因此,可以使用@Harsh的第二条建议,或者如果要进行强制更新,请不要调用
Add
而只需将account
的State
设置为Modified
。 This will attach it and mark it as modified w/o affecting the associated Customer
. 这将附加它并将其标记为已修改,而不会影响关联的
Customer
。
using (var db = new MainContext())
{
// disconnected record
var account = new Account()
{
Id = accountId,
AccountNumber = "9876",
Customer = new Customer() {Id = customerId}
};
db.Entry(account).State = EntityState.Modified; // <-- enough
db.SaveChanges();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.