linq2sql代码生成器在属性字段上放置一个属性,类似于:
[Column(Storage="_Message", DbType="NVarChar(20)")]
在运行时提取和使用这些信息很简单:
public class Row
{
// normally generated by LINQ2SQL
[Column(Storage = "_Message", DbType = "NVarChar(20)")]
public string Message
{
get;
set;
}
// normally generated by LINQ2SQL
[Column(Storage = "_Property", DbType = "NVarChar(20) NOT NULL")]
public string Property
{
get;
set;
}
}
public class VarCharInfo
{
public int? MaxLen;
public bool IsNullable;
}
public static VarCharInfo GetVarCharInfo(PropertyInfo propertyInfo)
{
var attrib = propertyInfo.GetCustomAttributes(typeof(ColumnAttribute), false)
.OfType<ColumnAttribute>()
.FirstOrDefault();
if (attrib == null || attrib.DbType == null)
{
return null;
}
var match = Regex.Match(attrib.DbType, @"VarChar\((?'len'\d+)\)(?'notnull' NOT NULL)?");
if (!match.Success)
{
return null;
}
var rvl = new VarCharInfo();
rvl.MaxLen = int.Parse(match.Groups["len"].Captures[0].Value);
rvl.IsNullable = match.Groups["notnull"].Success;
return rvl;
}
public static bool ValidateVarCharColumns(object dataObject)
{
bool success = true;
foreach (var propertyInfo in dataObject.GetType()
.GetProperties()
.Where(pi => pi.PropertyType == typeof(string)))
{
var vci = GetVarCharInfo(propertyInfo);
if (vci != null)
{
var currentValue = propertyInfo.GetGetMethod()
.Invoke(dataObject, null) as string;
if (currentValue == null)
{
if (!vci.IsNullable)
{
// more work: value is null but it shouldn't be
success = false;
}
}
else if (vci.MaxLen != null && currentValue.Length > vci.MaxLen)
{
// more work: value is longer than db allows
success = false;
}
}
}
return success;
}
static void UsageTest()
{
Row t = new Row();
t.Message = "this message is longer than 20 characters";
// t.Property is null
ValidateVarCharColumns(t); // returns false!
}