首页 > 解决方案 > 忽略数据模型中的属性,同时将它们保留在 EF Core 迁移和数据库表中

问题描述

我的模型中有属性,例如

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; }
}

在这里,我正在使用这个测试类使用迁移在数据库中创建表,现在表已成功创建,但问题是当我想使用像“ Select Title from Test where Id=1”这样的存储过程进行任何操作时,当我运行这个时,我遇到了错误像这样

“‘FromSql’操作的结果中不存在所需的列‘CreatedDate’”

我用过

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

  2. 还可以使用 Shadow 属性和 Ignore 属性,例如

      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 属性,并且在添加和更新新迁移时也不想从数据库中删除这些列。

标签: asp.net-corestored-proceduresentity-framework-coreef-code-first

解决方案


“‘FromSql’操作的结果中不存在所需的列‘CreatedDate’”

首先你要知道,这个错误的根本问题不是你的 CreatedDate 字段,而是你执行 FromSql 后返回的类型

执行FromSql时,返回类型为Test,Test类型包含所有字段(Id,Title,CreatedDate...),但是你的存储过程只选择了Title字段,所以接收到的类型不匹配,出现这个错误.

您可以通过两种方法解决此问题。

第一种方法是更改​​存储过程以返回与Test类型一致的数据。

Select * from Test where Id=1

另一种方法从receiving types.

您可以自定义 FromSql 方法以使返回的类型为dynamic

 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;
        }
    }

使用它:</p>

  var result = _context.FromSql("spName @Id", new Dictionary<string, object> { { "@Id", 1 } }).ToList(); 

推荐阅读