忽略数据模型中的属性,同时将它们保留在 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"

我用过

  1. NotMapped 属性工作正常,但是当我添加另一个迁移时,NotMapped 属性在更新数据库后从数据库中删除

  2. 也使用像

    这样的阴影属性和忽略属性
      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();