У меня проблемы с обновлением сущностей при многократном обращении к одной и той же таблице в одной сущности.
У меня есть два класса 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, если это возможно.)
Пример
Боб и Джим находятся в таблице User
, а затем есть Expense
Бод, изначально модифицированный Expense
, поэтому ModifiedByUserId
установлен на Боба 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);
}