获取实体框架模型第一个实体名称动态

本文关键字:实体 动态 模型 框架 获取 第一个 | 更新日期: 2023-09-27 18:32:48

我想做这样的事情:获取Entity FrameworkEntity的列名。

我不想直接使用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-caseIf-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();
    }
}