获取实体框架模型第一个实体名称动态
本文关键字:实体 动态 模型 框架 获取 第一个 | 更新日期: 2023-09-27 18:32:48
我想做这样的事情:获取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
。
为什么我需要这个?我必须在 API 中以 JSON 形式返回数据。我们创建了一个将实体模型转换为我们的类的方法,没有任何关系:
实体类:
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);
}
如果我返回一个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>
,然后我会返回List<Myfoo>
.
现在创建这个类每天都在浪费我的时间,我想创建一个生成器来创建MyFoo
和生成器来填充Lis<MyFoo>
List<Foo>
。
如果您有标准定义的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;
}
我从实体获取所有属性,请注意EntityName
应该包含命名空间,例如: 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();
}
}