忽略数据模型中的属性,同时将它们保留在 EF Core 迁移和数据库表中
Ignore properties in data model while keeping them in EF Core migrations and Database Tabel
我的模型中有像
这样的属性
public class Test{
public int Id{ get; set; }
public string Title { get; set; }
public DateTime? CreatedDate { get; set; }
public DateTime? ModifiedDate { get; set; }
public DateTime? DeletedDate { get; set; }
}
在这里,我使用此测试 class 来使用迁移在数据库中创建 Table,
现在 table 已成功创建,但问题是当我想使用类似于“Select Title from Test where Id=1
”的存储过程进行任何操作时,当我 运行 时,我会遇到这样的错误
"The required column 'CreatedDate' was not present in the results of a
'FromSql' operation"
我用过
NotMapped 属性工作正常,但是当我添加另一个迁移时,NotMapped 属性在更新数据库后从数据库中删除
也使用像
这样的阴影属性和忽略属性
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Test>().Property<DateTime?>("CreatedDate");
modelBuilder.Entity<Test>().Property<DateTime?>("ModifiedDate");
modelBuilder.Entity<Test>().Property<DateTime?>("DeletedDate");
}
也试试这个,
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder.Entity<Test>().Ignore(x => x.DeletedDate);
modelBuilder.Entity<Test>().Ignore(x => x.IsDeleted);
modelBuilder.Entity<Test>().Ignore(x => x.ModifiedDate); }
但问题依旧,
所以问题是我想在执行数据库操作时忽略 CreateDate、ModifiedDated、DeletedDated 属性,并且在添加和更新新迁移时也不想从数据库中删除这些列。
"The required column 'CreatedDate' was not present in the results of a
'FromSql' operation"
首先你要知道这个错误的根本问题不是你的CreatedDate字段,而是你return执行FromSql后的类型。
执行FromSql时,return类型为Test
,Test类型包含所有字段(Id,Title,CreatedDate...),但是你存储的程序只选择了Title
字段,因此接收到的类型不匹配,出现这个错误。
您可以通过两种方法解决这个问题。
第一种方法是将存储过程改为return与Test
类型一致的数据
Select * from Test where Id=1
另一种方法从receiving types
的角度变化。
可以自定义FromSql方法使returned类型动态.
public static class CustomFromSqlTest
{
public static IEnumerable<dynamic> FromSql(this DbContext dbContext, string Sql, Dictionary<string, object> Parameters)
{
using (var cmd = dbContext.Database.GetDbConnection().CreateCommand())
{
cmd.CommandText = Sql;
if (cmd.Connection.State != ConnectionState.Open)
cmd.Connection.Open();
foreach (KeyValuePair<string, object> param in Parameters)
{
DbParameter dbParameter = cmd.CreateParameter();
dbParameter.ParameterName = param.Key;
dbParameter.Value = param.Value;
cmd.Parameters.Add(dbParameter);
}
//var retObject = new List<dynamic>();
using (var dataReader = cmd.ExecuteReader())
{
while (dataReader.Read())
{
var dataRow = GetDataRow(dataReader);
yield return dataRow;
}
}
}
}
private static dynamic GetDataRow(DbDataReader dataReader)
{
var dataRow = new ExpandoObject() as IDictionary<string, object>;
for (var fieldCount = 0; fieldCount < dataReader.FieldCount; fieldCount++)
dataRow.Add(dataReader.GetName(fieldCount), dataReader[fieldCount]);
return dataRow;
}
}
使用它:
var result = _context.FromSql("spName @Id", new Dictionary<string, object> { { "@Id", 1 } }).ToList();
我的模型中有像
这样的属性public class Test{
public int Id{ get; set; }
public string Title { get; set; }
public DateTime? CreatedDate { get; set; }
public DateTime? ModifiedDate { get; set; }
public DateTime? DeletedDate { get; set; }
}
在这里,我使用此测试 class 来使用迁移在数据库中创建 Table,
现在 table 已成功创建,但问题是当我想使用类似于“Select Title from Test where Id=1
”的存储过程进行任何操作时,当我 运行 时,我会遇到这样的错误
"The required column 'CreatedDate' was not present in the results of a 'FromSql' operation"
我用过
NotMapped 属性工作正常,但是当我添加另一个迁移时,NotMapped 属性在更新数据库后从数据库中删除
也使用像
这样的阴影属性和忽略属性protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Test>().Property<DateTime?>("CreatedDate"); modelBuilder.Entity<Test>().Property<DateTime?>("ModifiedDate"); modelBuilder.Entity<Test>().Property<DateTime?>("DeletedDate"); }
也试试这个,
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder.Entity<Test>().Ignore(x => x.DeletedDate);
modelBuilder.Entity<Test>().Ignore(x => x.IsDeleted);
modelBuilder.Entity<Test>().Ignore(x => x.ModifiedDate); }
但问题依旧,
所以问题是我想在执行数据库操作时忽略 CreateDate、ModifiedDated、DeletedDated 属性,并且在添加和更新新迁移时也不想从数据库中删除这些列。
"The required column 'CreatedDate' was not present in the results of a 'FromSql' operation"
首先你要知道这个错误的根本问题不是你的CreatedDate字段,而是你return执行FromSql后的类型。
执行FromSql时,return类型为Test
,Test类型包含所有字段(Id,Title,CreatedDate...),但是你存储的程序只选择了Title
字段,因此接收到的类型不匹配,出现这个错误。
您可以通过两种方法解决这个问题。
第一种方法是将存储过程改为return与Test
类型一致的数据
Select * from Test where Id=1
另一种方法从receiving types
的角度变化。
可以自定义FromSql方法使returned类型动态.
public static class CustomFromSqlTest
{
public static IEnumerable<dynamic> FromSql(this DbContext dbContext, string Sql, Dictionary<string, object> Parameters)
{
using (var cmd = dbContext.Database.GetDbConnection().CreateCommand())
{
cmd.CommandText = Sql;
if (cmd.Connection.State != ConnectionState.Open)
cmd.Connection.Open();
foreach (KeyValuePair<string, object> param in Parameters)
{
DbParameter dbParameter = cmd.CreateParameter();
dbParameter.ParameterName = param.Key;
dbParameter.Value = param.Value;
cmd.Parameters.Add(dbParameter);
}
//var retObject = new List<dynamic>();
using (var dataReader = cmd.ExecuteReader())
{
while (dataReader.Read())
{
var dataRow = GetDataRow(dataReader);
yield return dataRow;
}
}
}
}
private static dynamic GetDataRow(DbDataReader dataReader)
{
var dataRow = new ExpandoObject() as IDictionary<string, object>;
for (var fieldCount = 0; fieldCount < dataReader.FieldCount; fieldCount++)
dataRow.Add(dataReader.GetName(fieldCount), dataReader[fieldCount]);
return dataRow;
}
}
使用它:
var result = _context.FromSql("spName @Id", new Dictionary<string, object> { { "@Id", 1 } }).ToList();