在一个实体中多次引用同一张表时,更新实体时遇到问题。
我有两个班User
和Expense
。 Expense
多次引用User
:
User
-谁支付了费用ApprovedUser
-谁批准了ProcessedUser
-谁处理ModifiedUser
-谁修改了费用 public class User
{
/// <summary>
/// User Id
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Key]
public string Id { get; set; }
/// <summary>
/// Display Name
/// </summary>
[Required]
[Display(Name = "Display Name")]
public string DisplayName { get; set; }
}
public class Expense
{
/// <summary>
/// User Id
/// </summary>
[Required]
[Display(Name = "User Id")]
public string UserId { get; set; }
/// <summary>
/// Linked User
/// </summary>
[ForeignKey("UserId")]
public User User { get; set; }
/// <summary>
/// Approved User Id
/// </summary>
[Display(Name = "Approved User Id")]
public string ApprovedUserId { get; set; } = null;
/// <summary>
/// Linked Approve User
/// </summary>
[ForeignKey("ApprovedUserId")]
public User ApprovedUser { get; set; }
/// <summary>
/// Processed User Id
/// </summary>
[Display(Name = "Processed User Id")]
public string ProcessedUserId { get; set; } = null;
/// <summary>
/// Linked Processed User
/// </summary>
[ForeignKey("ProcessedUserId")]
public User ProcessedUser { get; set; }
/// <summary>
/// Modified User Id
/// </summary>
[Display(Name = "Modified By User Id")]
public string ModifiedByUserId { get; set; }
/// <summary>
/// Linked Modified User
/// </summary>
[ForeignKey("ModifiedByUserId")]
public User ModifiedBy { get; set; }
}
当我更新字段ModifiedByUserId
时,我得到以下信息:
A referential integrity constraint violation occurred: The property value(s) of 'User.Id' on one end of a relationship do not match the property value(s) of 'Expense.ModifiedByUserId' on the other end.
但是,如果我将ModifiedByUserId
设为空,它将正常更新。
我还尝试过将ModifiedBy
设为空,并为ModifiedByUserId
设置相同的结果。
我看过多个SO帖子,花了12个小时试图弄清楚什么看起来应该很简单,但是我却找不到任何可行的方法。
(如果可能,我宁愿不要使用流利的api。)
示例
Bob和Jim在User
表中,然后有一个Expense
Bod,最初对Expense
进行了修改,因此ModifiedByUserId
被设置为Bob的User.Id
。我现在已经编辑了Expense
,所以ModifiedByUserId
现在应该是我的User.Id
。 User
中没有任何变化,只有Expense
生成的SQL
create table [dbo].[Expense] (
[Id] [int] not null identity,
[SubmittedDate] [datetime2](7) not null,
[UserId] [nvarchar](128) not null,
[ApprovedUserId] [nvarchar](128) null,
[ProcessedUserId] [nvarchar](128) null,
[State] [int] not null,
[ModifiedByUserId] [nvarchar](128) null,
[LastNotification] [datetime2](7) not null,
[NextNotification] [datetime2](7) not null,
[NumberOfNotifications] [int] not null,
[StopNotifications] [bit] not null,
[Inserted] [datetime2](7) not null,
[Updated] [datetime2](7) not null,
[Deleted] [bit] not null,
primary key ([Id])
);
create table [dbo].[User] (
[Id] [nvarchar](128) not null,
[DisplayName] [nvarchar](max) not null,
[Department] [nvarchar](max) null,
[JobTitle] [nvarchar](max) null,
[Email] [nvarchar](max) not null,
[TelephoneNumber] [nvarchar](max) null,
[MobileNumber] [nvarchar](max) null,
[DownloadedProfileImg] [bit] not null,
[ManagerId] [nvarchar](128) null,
[Deleted] [bit] not null,
primary key ([Id])
);
alter table [dbo].[Expense] add constraint [Expense_ApprovedUser] foreign key ([ApprovedUserId]) references [dbo].[User]([Id]);
alter table [dbo].[Expense] add constraint [Expense_ModifiedBy] foreign key ([ModifiedByUserId]) references [dbo].[User]([Id]);
alter table [dbo].[Expense] add constraint [Expense_ProcessedUser] foreign key ([ProcessedUserId]) references [dbo].[User]([Id]);
alter table [dbo].[Expense] add constraint [Expense_User] foreign key ([UserId]) references [dbo].[User]([Id]);
alter table [dbo].[User] add constraint [User_Manager] foreign key ([ManagerId]) references [dbo].[User]([Id]);
代码
var expense = await ExpenseService.GetExpense(4);
expense.Updated = DateTime.Now;
expense.ModifiedByUserId = "user_id_string";
await ExpenseService.Update(expense);
GetExpense
public async Task<Expense> GetExpense(int? id)
{
var expense = await Expenses.Query()
.Include(x => x.User)
.Include(x => x.ModifiedBy)
.Include(x => x.ApprovedUser)
.Include(x => x.ProcessedUser)
.FirstAsync(x => x.Id == id);
return expense;
}
更新费用:
public async Task<Expense> Update(Expense expense)
{
Expenses.Update(expense);
await Context.SaveAsync();
return expense;
}
存储库更新
public void Update(TEntity entity)
{
_dbSet.Attach(entity);
_context.SetState(entity, EntityState.Modified);
}