C#EF CF-违反参照完整性约束:同一张表具有多个外键

时间:2019-06-23 03:13:57

标签: c# entity-framework foreign-keys

在一个实体中多次引用同一张表时,更新实体时遇到问题。

我有两个班UserExpenseExpense多次引用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.IdUser中没有任何变化,只有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);
        }

0 个答案:

没有答案