使用具有特殊辅助属性的 Dapper.Contrib 更新,类
Use Dapper.Contrib Update, with classes that have special helper properties
我是 Dapper
和 Dapper.Contrib
的新手。有一个像这样的 class 数据库中有一个同名的 table:
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}";
}
}
}
我需要将 class 的整个列表更新到数据库。我使用:
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 { }
Computed在代码中的用法:
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;
}
现在注意上面为 Computed 粘贴的函数 ComputedPropertiesCache
它调用方法 TypePropertiesCache
,因此会发生什么,它将排除这两个属性(Write("false")
和 Computed
),但是 Write
属性用于从缓存中排除类型 属性,缓存是使用 ConcurrentDictionary
创建的,它的 Computed
,这非常适合您的用例。希望它能像预期的那样有所帮助。
我是 Dapper
和 Dapper.Contrib
的新手。有一个像这样的 class 数据库中有一个同名的 table:
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}";
}
}
}
我需要将 class 的整个列表更新到数据库。我使用:
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 { }
Computed在代码中的用法:
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;
}
现在注意上面为 Computed 粘贴的函数 ComputedPropertiesCache
它调用方法 TypePropertiesCache
,因此会发生什么,它将排除这两个属性(Write("false")
和 Computed
),但是 Write
属性用于从缓存中排除类型 属性,缓存是使用 ConcurrentDictionary
创建的,它的 Computed
,这非常适合您的用例。希望它能像预期的那样有所帮助。