2017-04-04 33 views
1

我是DapperDapper.Contrib的新手。有這樣的一類,有一個表中的數據庫具有相同的名稱:使用Dapper.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'.' 

如何解決這一問題?

+0

檢查[this](http://stackoverflow.com/a/26766350/1559611),Dapper.Contrib有一個選項可以將該屬性標記爲Computed並因此忽略它 –

+0

還有'[Write(true/false )]'屬性。你能解釋''[Computed]'和'[Write(true/false)]'之間有什麼區別嗎? – vaheeds

+1

您需要忽略的是[[Computed]],另一個會關注屬性是否可以更新(true/false),因爲值將從https://github.com/發送到數據庫DML –

回答

1

複製從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>具有以下共同DE:

var computedProperties = ComputedPropertiesCache(type); 

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

現在allPropertiesExceptKeyAndComputed在代碼進一步處理。在代碼IsWriteable的

WriteAttribute

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

用法:

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

現在請注意上面粘貼的已計算它調用的方法TypePropertiesCache功能ComputedPropertiesCache,從而會發生什麼是,它會排除這兩個屬性(Write("false")Computed),但Write屬性意味着將Type屬性從緩存中排除,該屬性是使用ConcurrentDictionary,它的Computed創建的,它非常適合您的用例。希望它能夠按預期發揮作用

+0

Thanks for the澄清!我知道它。 – vaheeds