sql-update - 使用 Dapper.Contrib Update,以及具有特殊帮助器属性的类

标签 sql-update code-first dapper dapper-contrib

我是 DapperDapper.Contrib 的新手。有一个这样的类,数据库中有一个同名的表:

public class Ware
{        
    public int ID { get; set; }
    public string Name { get; set; }
    public short UnitID { get; set; }
    public short TypeID { get; set; }
    public int CableCodeID { get; set; }
    public string Tag1 { get; set; }
    public string Tag2 { get; set; }
    public bool Discontinued { get; set; }
    public decimal Stock { get; set; } //this is not in database. this is helper
    public string UnitCaption { get; set; } //this is not in database. this is helper
    public string TypeCaption { get; set; } //this is not in database. this is helper
    public string FullCaption //this is not in database. this is helper
    {
        get
        {
            return $"{ID} {Name}";
        }
    }
}

我需要将此类的整个列表更新到数据库。我使用:

conection.Update(myList); // myList is List<Ware>

但是运行时出现错误:

System.Data.SqlClient.SqlException: 'Invalid column name 'Stock'.'
System.Data.SqlClient.SqlException: 'Invalid column name 'UnitCaption'.'
System.Data.SqlClient.SqlException: 'Invalid column name 'TypeCaption'.'
System.Data.SqlClient.SqlException: 'Invalid column name 'FullCaption'.'

如何解决这个问题?

最佳答案

复制 Dapper.Contrib 中的代码源代码:

计算

    [AttributeUsage(AttributeTargets.Property)]
    public class ComputedAttribute : Attribute { }

代码中计算的用法:

private static List<PropertyInfo> ComputedPropertiesCache(Type type)
{
            IEnumerable<PropertyInfo> pi;
            if (ComputedProperties.TryGetValue(type.TypeHandle, out pi))
            {
                return pi.ToList();
            }

            var computedProperties = TypePropertiesCache(type).Where(p => p.GetCustomAttributes(true).Any(a => a is ComputedAttribute)).ToList();

            ComputedProperties[type.TypeHandle] = computedProperties;
            return computedProperties;
}

现在 Insert<T>Update<T>有以下代码:

var computedProperties = ComputedPropertiesCache(type);

var allPropertiesExceptKeyAndComputed = allProperties.Except(keyProperties.Union(computedProperties)).ToList();

现在allPropertiesExceptKeyAndComputed在代码中进一步处理。

WriteAttribute

 public class WriteAttribute : Attribute
 {
    public WriteAttribute(bool write)
    {
       Write = write;
    }
    public bool Write { get; }
}

代码中 IsWriteable 的用法:

 private static List<PropertyInfo> TypePropertiesCache(Type type)
 {
    IEnumerable<PropertyInfo> pis;
    if (TypeProperties.TryGetValue(type.TypeHandle, out pis))
    {
       return pis.ToList();
    }

    var properties = type.GetProperties().Where(IsWriteable).ToArray();
    TypeProperties[type.TypeHandle] = properties;
    return properties.ToList();
 }

 private static bool IsWriteable(PropertyInfo pi)
 {
     var attributes = pi.GetCustomAttributes(typeof(WriteAttribute), false).AsList();
     if (attributes.Count != 1) return true;

     var writeAttribute = (WriteAttribute)attributes[0];
     return writeAttribute.Write;
 }

现在请注意函数ComputedPropertiesCache上面粘贴的计算它调用方法 TypePropertiesCache ,因此会发生的情况是,它将排除这两个属性( Write("false")Computed ),但是 Write属性旨在从缓存中排除 Type 属性,该属性是使用 ConcurrentDictionary 创建的,其Computed ,这非常适合您的用例。希望它能像预期的那样有所帮助。

关于sql-update - 使用 Dapper.Contrib Update,以及具有特殊帮助器属性的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43198468/

相关文章:

android - 如何更新android sqlite数据库中的新行

sql-server - 如何停止EF4.1 Code-First为实体PK创建Culstered索引

c# - 用于管理 Entity Framework 代码优先迁移的 GUI 或 Visual Studio 插件

testing - 小巧玲珑。 IoC、测试和 Agatha

c# - 使用 Dapper 的 SQLite。分析列时出错。无法将 System.Int64 类型的对象转换为 System.Double 类型

mysql - 在 SQL 的单个更新语句中更新多列时的更新顺序

mysql - 在更新查询中选择查询

mysql - 在存储过程中更新和删除

c# - EF Code first CTP 5 中 MapHierarchy() 的替代方案

sql-server - Dapper:无法解析 float (解析列时出错)