【发布时间】:2017-07-11 17:10:09
【问题描述】:
我正在使用 EF Core 并尝试更新实体的列/属性。
该列有一个外键约束...可以为空并且是一个 int。
同一个表/实体有三个或四个其他列/属性相同的数据类型也有外键约束......并且可以为空
当我使用更新命令更新任何这些列的值时...它工作得非常好...除了一列。当我尝试更新该列并处理更新时,它将保存所有更改...但该列只是将其恢复为以前的值。
它不会抛出异常......没有任何类型的错误......只是将其恢复为原始值并继续。
以下是实体的上下文条目....有问题的列是 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);
下面是几张图片,显示了数据库中对列的外键约束的配置以及列的属性。
如果有人知道为什么这一列会拒绝正确更新,那将是一个很大的帮助。
更新:::
我创建了复制数据库结构并生成测试数据的 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
【问题讨论】:
-
更新外键值后是否加载更多数据?
-
关系走向何方?更新汽车表中的键不会破坏与其他表的关系吗?
-
我没有进一步更新或加载数据。它的一个简单的获取记录修改属性和更新实体。至于更新密钥..我没有更新 car 表中的密钥..我将 app 表中的引用列更新为 car 表中不同的可行记录。
-
如上所述...我可以更新此实体上的任何列/属性。只是不是 car_app_id 值。为什么我可以更新内置类型 ID 或应用类型 ID 就好了..但是当我尝试更新 car_app_id 时。它只是恢复该值并继续前进......该列不会更新的内容是什么。该值是有效的......它是一个有效的记录,因此它不会违反约束......并且管理器中的所有更新方法都是实例化存储库并将存储库调用到 TblApps 对象并调用更新方法。跨度>
标签: c# entity-framework asp.net-core