获取 Entity Framework 模型第一个实体名称动态
Get Entity Framework Model first Entity Name dynamic
我想做这样的事情:
获取 Entity Framework
中的 Entity
的列名。
我不想直接使用 Entity Name
,我想将 Entity-Name
作为字符串传递给方法。
public HttpResponseMessage GetColumnName(string MyClassName)
{
var db = new DAL.MyEntities();
var names = typeof(db.MyClassName).GetProperties()
.Select(property => property.Name)
.ToArray();
return new HttpRequestMessage().CreateResponse(HttpStatusCode.OK, names, new HttpConfiguration().Formatters.JsonFormatter);
}
注意:我不想使用 switch-case
或 If-else
。
为什么我需要这个?
我必须将 return 中的数据 API 作为 JSON 。
我们创建了一个将实体模型转换为我们的 class 没有任何关系的方法:
实体Class:
public partial class foo
{
public foo()
{
this.parent = new HashSet<parent>();
this.child = new HashSet<child>();
}
public int id { get; set; }
public string title { get; set; }
public virtual ICollection<parent> parent { get; set; }
public virtual ICollection<child> child { get; set; }
}
我想称呼这个API:
public HttpResponseMessage GetFooData()
{
var db = new DAL.MyEntities();
var data = db.foos.ToList();
return new HttpRequestMessage().CreateResponse(HttpStatusCode.OK, data, new HttpConfiguration().Formatters.JsonFormatter);
}
如果我Return一个List<foo> data
会得到这个错误:
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.
为了解决这个问题,我必须创建另一个与实体模型相同的模型,没有像这样的任何子项和父项:
public partial class Myfoo
{
public int id { get; set; }
public string title { get; set; }
}
然后我将循环 List<foo>
并填充 List<Myfoo>
,然后我将 return List<Myfoo>
.
现在创建这个 class 每天都在浪费我的时间,我想创建一个生成 MyFoo
的生成器和一个用 List<Foo>
填充 Lis<MyFoo>
的生成器。
如果您定义了标准 DbContext
:
public class MyEntities : DbContext
{
//..
public DbSet<MyEntity> MyEntites { get; set; }
//..
}
你需要使用反射
var db = new DAL.MyEntities();
var type = db.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(pr => pr.PropertyType.IsGenericType)
.Where(pr => pr.PropertyType.GetGenericTypeDefinition() ==
typeof(DbSet<>))
.Select(pr => pr.PropertyType.GetGenericArguments().Single())
.SingleOrDefault(t => t.Name == MyClassName);
if (type == null) / * type not found case */ ;
var names = type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Select(property => property.Name)
.ToArray();
我的问题已解决,如下所示:
public List<string> GetServiceModelProprty(string EntityName, bool ShowGeneric = false)
{
List<string> ProNames = new List<string>();
var names = Type.GetType(EntityName)
.GetProperties()
.Select(p => p.Name).ToArray();
ProNames.AddRange(names);
return ProNames;
}
我从 Entity 获得了所有 属性,请注意 EntityName
应该包含 NameSpace,例如:DAL.MyClassName
这也是我的映射生成器:
public class MapperGenerator
{
/// <summary>
///
/// </summary>
/// <param name="FullEntityName">Entity Name in DataBase Contain NameSpace</param>
/// <param name="ServiceModelName"></param>
/// <param name="MapperFunctionName"></param>
/// <param name="NeedHtmlBreak"></param>
/// <returns></returns>
public string GenerateMapperString(string FullEntityName, string ServiceModelName, string MapperFunctionName, bool NeedHtmlBreak)
{
List<string> PropNames = new List<string>();
var names = new ECBVendorDAL.DataMapperGenerator().GetServiceModelProprty(FullEntityName);
PropNames.AddRange(names);
// DB Entity
string EntityName = FullEntityName.Split('.')[1];
//Service Model
string B_SM = ServiceModelName;
// Function In Mapper
string strFunc = MapperFunctionName;
StringBuilder sb = new StringBuilder();
// A>B
sb.Append(GetModelString(PropNames, EntityName, ServiceModelName, strFunc, NeedHtmlBreak, false));
// B>A
sb.Append(GetModelString(PropNames, ServiceModelName, EntityName, strFunc, NeedHtmlBreak, false));
//List<A> to List<B>
sb.Append(GetModelString(PropNames, EntityName, ServiceModelName, strFunc, NeedHtmlBreak, true));
//List<B> to List<A>
sb.Append(GetModelString(PropNames, ServiceModelName, EntityName, strFunc, NeedHtmlBreak, true));
return sb.ToString();
}
private string GetModelString(List<string> ColunNames, string ReturnedClass, string PassedClass, string strFunctionName, bool ApplyHtmlBr, bool IsList = false)
{
string htmlBr = ApplyHtmlBr ? "<br />" : string.Empty;
StringBuilder Sb = new StringBuilder();
if (IsList)
{
#region dbModelName To dbServiceModelName
//public static List<VendorServiceModel> GetVendorServiceModel(ICollection<ECB_Vendor> input)
Sb.Append("<xmp>");
Sb.Append(string.Format("public static List<{0}> {2}(ICollection<{1}> input)", ReturnedClass, PassedClass, strFunctionName));
Sb.Append("</xmp>" + htmlBr);
Sb.Append("{" + htmlBr);
// - - - - - List<VendorServiceModel> result = new List<VendorServiceModel>();
Sb.Append("<xmp>");
Sb.Append(string.Format(" List<{0}> result = new List<{0}>();", ReturnedClass));
Sb.Append("</xmp>" + htmlBr);
Sb.Append("foreach (var item in input)" + htmlBr);
Sb.Append("{" + htmlBr);
Sb.Append("<xmp>");
Sb.Append(string.Format("result.Add({0}(item));", strFunctionName));
Sb.Append("</xmp>" + htmlBr);
Sb.Append("}" + htmlBr);
Sb.Append("return result;" + htmlBr);
Sb.Append("}" + htmlBr);
#endregion
}
else
{
#region One - PassedClass To ReturnedClass
Sb.Append(htmlBr);
Sb.Append(string.Format("public static {0} {2}({1} input)" + htmlBr, ReturnedClass, PassedClass, strFunctionName));
Sb.Append("{" + htmlBr);
Sb.Append(string.Format("return new {0}()", ReturnedClass));
Sb.Append("{" + htmlBr);
foreach (var item in ColunNames)
{
Sb.Append(string.Format("{0} = input.{0} , " + htmlBr, item));
}
Sb.Append("};" + htmlBr);
Sb.Append("}" + htmlBr);
Sb.Append(htmlBr);
#endregion
}
return Sb.ToString();
}
}
我想做这样的事情:
获取 Entity Framework
中的 Entity
的列名。
我不想直接使用 Entity Name
,我想将 Entity-Name
作为字符串传递给方法。
public HttpResponseMessage GetColumnName(string MyClassName)
{
var db = new DAL.MyEntities();
var names = typeof(db.MyClassName).GetProperties()
.Select(property => property.Name)
.ToArray();
return new HttpRequestMessage().CreateResponse(HttpStatusCode.OK, names, new HttpConfiguration().Formatters.JsonFormatter);
}
注意:我不想使用 switch-case
或 If-else
。
为什么我需要这个? 我必须将 return 中的数据 API 作为 JSON 。 我们创建了一个将实体模型转换为我们的 class 没有任何关系的方法:
实体Class:
public partial class foo
{
public foo()
{
this.parent = new HashSet<parent>();
this.child = new HashSet<child>();
}
public int id { get; set; }
public string title { get; set; }
public virtual ICollection<parent> parent { get; set; }
public virtual ICollection<child> child { get; set; }
}
我想称呼这个API:
public HttpResponseMessage GetFooData()
{
var db = new DAL.MyEntities();
var data = db.foos.ToList();
return new HttpRequestMessage().CreateResponse(HttpStatusCode.OK, data, new HttpConfiguration().Formatters.JsonFormatter);
}
如果我Return一个List<foo> data
会得到这个错误:
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.
为了解决这个问题,我必须创建另一个与实体模型相同的模型,没有像这样的任何子项和父项:
public partial class Myfoo
{
public int id { get; set; }
public string title { get; set; }
}
然后我将循环 List<foo>
并填充 List<Myfoo>
,然后我将 return List<Myfoo>
.
现在创建这个 class 每天都在浪费我的时间,我想创建一个生成 MyFoo
的生成器和一个用 List<Foo>
填充 Lis<MyFoo>
的生成器。
如果您定义了标准 DbContext
:
public class MyEntities : DbContext
{
//..
public DbSet<MyEntity> MyEntites { get; set; }
//..
}
你需要使用反射
var db = new DAL.MyEntities();
var type = db.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(pr => pr.PropertyType.IsGenericType)
.Where(pr => pr.PropertyType.GetGenericTypeDefinition() ==
typeof(DbSet<>))
.Select(pr => pr.PropertyType.GetGenericArguments().Single())
.SingleOrDefault(t => t.Name == MyClassName);
if (type == null) / * type not found case */ ;
var names = type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Select(property => property.Name)
.ToArray();
我的问题已解决,如下所示:
public List<string> GetServiceModelProprty(string EntityName, bool ShowGeneric = false)
{
List<string> ProNames = new List<string>();
var names = Type.GetType(EntityName)
.GetProperties()
.Select(p => p.Name).ToArray();
ProNames.AddRange(names);
return ProNames;
}
我从 Entity 获得了所有 属性,请注意 EntityName
应该包含 NameSpace,例如:DAL.MyClassName
这也是我的映射生成器:
public class MapperGenerator
{
/// <summary>
///
/// </summary>
/// <param name="FullEntityName">Entity Name in DataBase Contain NameSpace</param>
/// <param name="ServiceModelName"></param>
/// <param name="MapperFunctionName"></param>
/// <param name="NeedHtmlBreak"></param>
/// <returns></returns>
public string GenerateMapperString(string FullEntityName, string ServiceModelName, string MapperFunctionName, bool NeedHtmlBreak)
{
List<string> PropNames = new List<string>();
var names = new ECBVendorDAL.DataMapperGenerator().GetServiceModelProprty(FullEntityName);
PropNames.AddRange(names);
// DB Entity
string EntityName = FullEntityName.Split('.')[1];
//Service Model
string B_SM = ServiceModelName;
// Function In Mapper
string strFunc = MapperFunctionName;
StringBuilder sb = new StringBuilder();
// A>B
sb.Append(GetModelString(PropNames, EntityName, ServiceModelName, strFunc, NeedHtmlBreak, false));
// B>A
sb.Append(GetModelString(PropNames, ServiceModelName, EntityName, strFunc, NeedHtmlBreak, false));
//List<A> to List<B>
sb.Append(GetModelString(PropNames, EntityName, ServiceModelName, strFunc, NeedHtmlBreak, true));
//List<B> to List<A>
sb.Append(GetModelString(PropNames, ServiceModelName, EntityName, strFunc, NeedHtmlBreak, true));
return sb.ToString();
}
private string GetModelString(List<string> ColunNames, string ReturnedClass, string PassedClass, string strFunctionName, bool ApplyHtmlBr, bool IsList = false)
{
string htmlBr = ApplyHtmlBr ? "<br />" : string.Empty;
StringBuilder Sb = new StringBuilder();
if (IsList)
{
#region dbModelName To dbServiceModelName
//public static List<VendorServiceModel> GetVendorServiceModel(ICollection<ECB_Vendor> input)
Sb.Append("<xmp>");
Sb.Append(string.Format("public static List<{0}> {2}(ICollection<{1}> input)", ReturnedClass, PassedClass, strFunctionName));
Sb.Append("</xmp>" + htmlBr);
Sb.Append("{" + htmlBr);
// - - - - - List<VendorServiceModel> result = new List<VendorServiceModel>();
Sb.Append("<xmp>");
Sb.Append(string.Format(" List<{0}> result = new List<{0}>();", ReturnedClass));
Sb.Append("</xmp>" + htmlBr);
Sb.Append("foreach (var item in input)" + htmlBr);
Sb.Append("{" + htmlBr);
Sb.Append("<xmp>");
Sb.Append(string.Format("result.Add({0}(item));", strFunctionName));
Sb.Append("</xmp>" + htmlBr);
Sb.Append("}" + htmlBr);
Sb.Append("return result;" + htmlBr);
Sb.Append("}" + htmlBr);
#endregion
}
else
{
#region One - PassedClass To ReturnedClass
Sb.Append(htmlBr);
Sb.Append(string.Format("public static {0} {2}({1} input)" + htmlBr, ReturnedClass, PassedClass, strFunctionName));
Sb.Append("{" + htmlBr);
Sb.Append(string.Format("return new {0}()", ReturnedClass));
Sb.Append("{" + htmlBr);
foreach (var item in ColunNames)
{
Sb.Append(string.Format("{0} = input.{0} , " + htmlBr, item));
}
Sb.Append("};" + htmlBr);
Sb.Append("}" + htmlBr);
Sb.Append(htmlBr);
#endregion
}
return Sb.ToString();
}
}