#region 根据模型生成FastReport需要的Frd字典文件
/// <summary>
/// 生成frd文件内容
/// </summary>
private static StringBuilder stringTouBu = new StringBuilder();
/// <summary>
/// 根据模型生成FastReport需要的Frd字典文件
/// </summary>
/// <param name="model">实体模型</param>
/// <param name="path">生成的frd存放的路径(后面不要带\)</param>
/// <param name="bindName">FastReport数据绑定名称,默认取实体模型名称</param>
/// <returns></returns>
/// <remarks>
/// Request by OP需要用FastReport Reponse by Smile 2022-08-03
/// </remarks>
public static string GenerateFRD<T>(this T model, string path, string bindName = null)
{
var t = model.GetType();
var properties = t.GetProperties();
stringTouBu.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
stringTouBu.AppendLine("<Dictionary>");
stringTouBu.AppendLine($"<BusinessObjectDataSource Name=\"{bindName ?? t.Name}\" ReferenceName=\"{bindName ?? t.Name}\" DataType=\"System.Int32\" Enabled=\"true\">");
foreach (var item in properties)
{
var name = item.Name;
var type = item.PropertyType.Name;
var isClass = item.PropertyType.IsClass;//获取一个值,该值指示 System.Type 是类还是委托; 也就是说,不是值类型或接口。
var isGenericType = item.PropertyType.IsGenericType;//获取一个值,该值指示当前类型是否为泛型类型。
var fullName = item.PropertyType.FullName;
// 表示实体模型 表示数组
if ((type != "String" && isClass && !isGenericType) || (isClass && isGenericType))
{
GenerateType(item.PropertyType, name);
}
else
{
stringTouBu.AppendLine($"<Column Name=\"{name}\" DataType=\"{GetType(type, fullName)}\" PropName=\"Column\"/>");
}
}
stringTouBu.AppendLine("</BusinessObjectDataSource>");
stringTouBu.AppendLine("</Dictionary>");
string filePath = $"{path}\\{bindName ?? t.Name}.frd";
if (!File.Exists(filePath))
{
File.Create(filePath);
}
System.IO.File.WriteAllText(filePath, stringTouBu.ToString());
return stringTouBu.ToString();
}
/// <summary>
/// 递归获取多层嵌套的模型
/// </summary>
/// <param name="t">模型(单个模型或者数组)</param>
/// <param name="bindName">数据源绑定的名称</param>
/// <returns></returns>
private static void GenerateType(Type t, string bindName)
{
stringTouBu.AppendLine($"<BusinessObjectDataSource Name=\"{bindName}\" ReferenceName=\"{bindName}\" DataType=\"System.Int32\" Enabled=\"true\">");
var count = t.GenericTypeArguments.Length;
var properties = count > 0 ? t.GenericTypeArguments[0].GetProperties() : t.GetProperties();
foreach (var item in properties)
{
var name = item.Name;
var type = item.PropertyType.Name;
var isClass = item.PropertyType.IsClass;//获取一个值,该值指示 System.Type 是类还是委托; 也就是说,不是值类型或接口。
var isGenericType = item.PropertyType.IsGenericType;//获取一个值,该值指示当前类型是否为泛型类型。
var fullName = item.PropertyType.FullName;
// 表示实体模型 表示数组
if ((type != "String" && isClass && !isGenericType) || (isClass && isGenericType))
{
GenerateType(item.PropertyType, name);
}
else
{
stringTouBu.AppendLine($"<Column Name=\"{name}\" DataType=\"{GetType(type, fullName)}\" PropName=\"Column\"/>");
}
}
stringTouBu.AppendLine("</BusinessObjectDataSource>");
}
/// <summary>
/// 获取数据类型空间
/// </summary>
/// <param name="type">原始type类型</param>
/// <param name="fullName"></param>
/// <returns></returns>
private static string GetType(string type, string fullName)
{
//判断值类型是否可为空 System.Nullable`1 固定的命名空间
if (type == "Nullable`1")
{
//可为空则获取不为空的命名类型
return fullName.Replace("System.Nullable`1[[", "").Replace("]]", "").Split(',')[0];
}
return fullName;
}
#endregion