繁体   English   中英

为什么EF Core Update无法更新已修改的列

[英]Why is EF Core Update failing to update a modified column

我正在使用EF Core,而我正在尝试更新实体的列/属性。

该列具有外键约束...可为空,并且为int。

相同的表/实体具有三个或四个其他列/属性,相同的数据类型也受外键约束...并且可以为空

当我使用Update命令更新这些列中任何一个的值时...它工作得很好...除了一列以外。 当我尝试更新该列并处理更新时,它将保存所有更改...但是该列会将其恢复为先前的值。

它不会引发异常..不会有任何类型的错误...只要将其恢复为原始值并继续。

以下是实体的上下文条目。...所涉及的列是car_app_id

上下文文件中没有任何东西可以区分该特定列与其他列...外键约束与其他列没有区别...

            {
            entity.HasKey(e => e.AppId)
                .HasName("PK_tbl_apps");

    entity.ToTable("tbl_apps");

            entity.Property(e => e.AppId).HasColumnName("app_id");

    entity.Property(e => e.Active).HasColumnName("active");

    entity.Property(e => e.AppAcro)
                .HasColumnName("app_acro")
                .HasColumnType("varchar(50)");

    entity.Property(e => e.AppDesc)
                .HasColumnName("app_desc")
                .HasColumnType("varchar(5000)");

    entity.Property(e => e.AppTypeId).HasColumnName("app_type_id");

    entity.Property(e => e.BuildTypeId).HasColumnName("build_type_id");

    entity.Property(e => e.CarAppId).HasColumnName("car_app_id");       

    entity.Property(e => e.ControlLevelId).HasColumnName("control_level_id");     

    entity.Property(e => e.Deleted).HasColumnName("deleted");

    entity.HasOne(d => d.AppType)
                .WithMany(p => p.TblApps)
                .HasForeignKey(d => d.AppTypeId)
                .HasConstraintName("FK_tbl_apps_tbl_app_types");

    entity.HasOne(d => d.BuildType)
                .WithMany(p => p.TblApps)
                .HasForeignKey(d => d.BuildTypeId)
                .HasConstraintName("FK_tbl_apps_tbl_build_types");

    entity.HasOne(d => d.CarApp)
                .WithMany(p => p.TblApps)
                .HasForeignKey(d => d.CarAppId)
                .HasConstraintName("FK_tbl_apps_tbl_car_apps");

    entity.HasOne(d => d.ControlLevel)
                .WithMany(p => p.TblApps)
                .HasForeignKey(d => d.ControlLevelId)
                .HasConstraintName("FK_tbl_apps_tbl_control_level");


});

这是我用来测试的代码。这是简单的测试代码,试图弄清楚为什么更新不起作用。 它非常基础的存储库

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        private omni_dbContext context { get; set; }
        private DbSet<TEntity> dbset { get; set; }
        public Repository()
        {
            try
            {
                context = new omni_dbContext();
                dbset = context.Set<TEntity>();

            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally { }
        }
        public IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null,
           params Expression<Func<TEntity, object>>[] includeProperties)
        {
            try
            {
                IQueryable<TEntity> query = dbset;
                if (filter != null)
                {
                    query = query.Where(filter);
                }
                if (includeProperties != null)
                {
                    foreach (var includeProperty in includeProperties)
                    {
                        query = query.Include(includeProperty);
                    }
                }
                return query.ToList();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally { }
        }



        public void Update(TEntity entity)
        {
            try
            {
                context.Update(entity);
                context.SaveChanges();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally { }
        }


    }
}

因此,我对实体使用Manager类来实例化存储库并进行数据调用。

基本上我得到了一组记录..选择一条记录...更新属性并将其发送回更新,每个字段都将更新得很好..但是实体将car_app_id属性重置为修改之前的状态我不明白为什么。

 EalmsEF.AppManager manager = new EalmsEF.AppManager();
                var apps = manager.GetActiveFull().Where(a => a.CarAppId != null).ToList();
                var app = apps[0];
                app.CarAppId = 2;
                app.BuildTypeId = 2;
                manager.Update(app);

下面的几个图像显示了数据库的外键约束到列的配置以及列的属性。

在此处输入图片说明 在此处输入图片说明

如果有人知道为什么这一栏拒绝正确更新,那将是一个很大的帮助。

UPDATE :::

我创建了复制数据库结构并生成测试数据的sql脚本。 基本上,您创建一个名为test..runt的数据库,并且使用此重复数据库创建了两个脚本,可以复制该问题。

    USE [test]
GO

/****** Object:  Table [dbo].[tbl_control_level]    Script Date: 2/21/2017 3:30:29 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[tbl_control_level](
    [control_level_id] [int] IDENTITY(1,1) NOT NULL,
    [control_level] [varchar](50) NULL,
    [description] [varchar](1000) NULL,
    [deleted] [bit] NULL,

 CONSTRAINT [PK_tbl_control_level] PRIMARY KEY CLUSTERED 
(
    [control_level_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO



/****** Object:  Table [dbo].[tbl_app_types]    Script Date: 2/21/2017 3:29:51 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[tbl_app_types](
    [app_type_id] [int] IDENTITY(1,1) NOT NULL,
    [app_type] [varchar](50) NULL,
    [deleted] [bit] NULL,   
 CONSTRAINT [PK_tbl_app_types] PRIMARY KEY CLUSTERED 
(
    [app_type_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO


/****** Object:  Table [dbo].[tbl_car_apps]    Script Date: 2/21/2017 3:31:32 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[tbl_car_apps](
    [car_app_id] [int] IDENTITY(1,1) NOT NULL,
    [car_id] [varchar](50) NULL,    
    [deleted] [bit] NULL,
     CONSTRAINT [PK_tbl_car_apps] PRIMARY KEY CLUSTERED 
(
    [car_app_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO



/****** Object:  Table [dbo].[tbl_control_level]    Script Date: 2/21/2017 3:30:29 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[tbl_control_level](
    [control_level_id] [int] IDENTITY(1,1) NOT NULL,
    [control_level] [varchar](50) NULL,
    [description] [varchar](1000) NULL,
    [deleted] [bit] NULL,

 CONSTRAINT [PK_tbl_control_level] PRIMARY KEY CLUSTERED 
(
    [control_level_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO




/****** Object:  Table [dbo].[tbl_build_types]    Script Date: 2/21/2017 3:29:15 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[tbl_build_types](
    [build_type_id] [int] IDENTITY(1,1) NOT NULL,
    [build_type] [varchar](50) NULL,
    [deleted] [bit] NULL,
 CONSTRAINT [PK_tbl_build_types] PRIMARY KEY CLUSTERED 
(
    [build_type_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO


/****** Object:  Table [dbo].[tbl_apps]    Script Date: 2/21/2017 3:25:58 PM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[tbl_apps](
    [app_id] [int] IDENTITY(1,1) NOT NULL,
    [app_acro] [varchar](50) NULL,
    [app_name] [varchar](100) NULL, 
    [app_type_id] [int] NULL,   
    [control_level_id] [int] NULL,
    [build_type_id] [int] NULL, 
    [car_app_id] [int] NULL,
    [deleted] [bit] NULL,

 CONSTRAINT [PK_tbl_apps] PRIMARY KEY CLUSTERED 
(
    [app_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[tbl_apps]  WITH CHECK ADD  CONSTRAINT [FK_tbl_apps_tbl_app_types] FOREIGN KEY([app_type_id])
REFERENCES [dbo].[tbl_app_types] ([app_type_id])
GO

ALTER TABLE [dbo].[tbl_apps] CHECK CONSTRAINT [FK_tbl_apps_tbl_app_types]
GO

ALTER TABLE [dbo].[tbl_apps]  WITH CHECK ADD  CONSTRAINT [FK_tbl_apps_tbl_build_types] FOREIGN KEY([build_type_id])
REFERENCES [dbo].[tbl_build_types] ([build_type_id])
GO

ALTER TABLE [dbo].[tbl_apps] CHECK CONSTRAINT [FK_tbl_apps_tbl_build_types]
GO

ALTER TABLE [dbo].[tbl_apps]  WITH CHECK ADD  CONSTRAINT [FK_tbl_apps_tbl_car_apps] FOREIGN KEY([car_app_id])
REFERENCES [dbo].[tbl_car_apps] ([car_app_id])
GO

ALTER TABLE [dbo].[tbl_apps] CHECK CONSTRAINT [FK_tbl_apps_tbl_car_apps]
GO

ALTER TABLE [dbo].[tbl_apps]  WITH CHECK ADD  CONSTRAINT [FK_tbl_apps_tbl_control_level] FOREIGN KEY([control_level_id])
REFERENCES [dbo].[tbl_control_level] ([control_level_id])
GO

ALTER TABLE [dbo].[tbl_apps] CHECK CONSTRAINT [FK_tbl_apps_tbl_control_level]
GO




     USE [test]
GO

INSERT INTO [dbo].[tbl_app_types]
           ([app_type]
           ,[deleted])
     VALUES
           ('app type 1'
           ,0)
GO

INSERT INTO [dbo].[tbl_app_types]
           ([app_type]
           ,[deleted])
     VALUES
           ('app type 2'
           ,0)
GO


INSERT INTO [dbo].[tbl_build_types]
           ([build_type]
           ,[deleted])
     VALUES
           ('build type 1'
           ,0)
GO

INSERT INTO [dbo].[tbl_build_types]
           ([build_type]
           ,[deleted])
     VALUES
           ('build type 2'
           ,0)
GO

INSERT INTO [dbo].[tbl_control_level]
           ([control_level]
           ,[description]
           ,[deleted])
     VALUES
           ('ct 1'
           ,''
           ,0)
GO

INSERT INTO [dbo].[tbl_control_level]
           ([control_level]
           ,[description]
           ,[deleted])
     VALUES
           ('ct 2'
           ,''
           ,0)
GO

INSERT INTO [dbo].[tbl_car_apps]
           ([car_id]
           ,[deleted])
     VALUES
           ('1'
           ,0)
GO

INSERT INTO [dbo].[tbl_car_apps]
           ([car_id]
           ,[deleted])
     VALUES
           ('2'
           ,0)
GO

INSERT INTO [dbo].[tbl_apps]
           ([app_acro]
           ,[app_name]
           ,[app_type_id]
           ,[control_level_id]
           ,[build_type_id]
           ,[car_app_id]
           ,[deleted])
     VALUES
           ('testapp1'
           ,''
           ,1
           ,1
           ,1
           ,1
           ,0)
GO

INSERT INTO [dbo].[tbl_apps]
           ([app_acro]
           ,[app_name]
           ,[app_type_id]
           ,[control_level_id]
           ,[build_type_id]
           ,[car_app_id]
           ,[deleted])
     VALUES
           ('testapp2'
           ,''
           ,1
           ,1
           ,1
           ,1
           ,0)
GO

看起来我想通了。

经过进一步调查,这就是我发现的...

要更新的实体在导航对象上带有包含。.so这个特定实例..CarApp对象包含在记录的“获取”中。 由于某种原因,这导致更新将更改重置为导航属性中设置的任何值。

出于好奇,我在get上添加了包括include的其他属性,并与它们开始了相同的行为...当我删除了所有导航属性的包含并尝试保存更新时,它运行良好。

因此,基本上,如果要使用包含导航属性的实体对实体进行更新,则约束列适用于..您也必须更新该属性..或者从已更新的属性中删除引用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM