질문하기질문하기
 

답변됨Entity Name reflector

  • 2008년 7월 4일 금요일 오전 7:33hnchass 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     

    Hi All

     

    I have a Blog entity with a Blog_ID field. Is it possible for me to do some reflector to get the Blog_ID and return it as string?

     

    It is because I am building a selectlist but don't want to hard code like this.

    new SelectList(blog,"blog_ID","blog_Description");

     

    I want to make it strong-typed, is it possible?

     

    Regards

    Alex

답변

  • 2008년 7월 4일 금요일 오전 9:05Vasco Oliveira 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨

    Yes, it's possible.

     

    In my opinion, the best way is to check EntityKeyMembers array of the EntityKey property of the Blog entity. You can then get a name list if your key fields.

     

    On the other hand you can use reflection on the Blog entity and iterate through all properties to see their CustomAttributes and check if it's of type EdmScalarPropertyAttribute and if so, see if EntityKeyProperty is true. For example, to get a list of all key properties:

     

     

    foreach (PropertyInfo prop in typeof(Blog).GetProperties())

    {

    object[] attrs = prop.GetCustomAttributes(false);

    foreach (object obj in attrs)

    {

    if (obj.GetType() == typeof(EdmScalarPropertyAttribute))

    {

    EdmScalarPropertyAttribute attr = (EdmScalarPropertyAttribute)obj;

    if (attr.EntityKeyProperty)

    keyList.Add(prop.Name);

    }

    }

    }

     

     

     

    Hope it helps

  • 2008년 7월 4일 금요일 오후 7:33Greg Bachraty 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨

    Instead of using strings or reflection you could consider lambda expressions.

    You can create a generic SelectList with this constructor:

    Code Snippet

    SelectList(T entity, Expression<Func<T,object>> field1, Expression<Func<T,object>> field2)

     

    Then you can use it like this with strong typing:

    Code Snippet

    new SelectList(blog, b=>blog_ID, b=>blog_Description);

     

    You don't even need to create a generic class if you don't want to and mine the corresponding strings from the expression trees above:

    Code Snippet

    static SelectList CreateList<T>(T entity, Expression<Func<T,object>> field1, Expression<Func<T,object>> field2)

    {

        string f1name = (field1.Body as MemberExpression).Member.Name;
        string f2name = (field2.Body as MemberExpression).Member.Name;

        return new SelectList(entity, f1name, f2name);
    }

     

    SelectList.Create(blog, b=>blog_ID, b=>blog_Description);

    Although this latter aproach will only throw a runtime exception if you use different expressions than the intended simple field access.

모든 응답

  • 2008년 7월 4일 금요일 오전 9:05Vasco Oliveira 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨

    Yes, it's possible.

     

    In my opinion, the best way is to check EntityKeyMembers array of the EntityKey property of the Blog entity. You can then get a name list if your key fields.

     

    On the other hand you can use reflection on the Blog entity and iterate through all properties to see their CustomAttributes and check if it's of type EdmScalarPropertyAttribute and if so, see if EntityKeyProperty is true. For example, to get a list of all key properties:

     

     

    foreach (PropertyInfo prop in typeof(Blog).GetProperties())

    {

    object[] attrs = prop.GetCustomAttributes(false);

    foreach (object obj in attrs)

    {

    if (obj.GetType() == typeof(EdmScalarPropertyAttribute))

    {

    EdmScalarPropertyAttribute attr = (EdmScalarPropertyAttribute)obj;

    if (attr.EntityKeyProperty)

    keyList.Add(prop.Name);

    }

    }

    }

     

     

     

    Hope it helps

  • 2008년 7월 4일 금요일 오후 7:33Greg Bachraty 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨

    Instead of using strings or reflection you could consider lambda expressions.

    You can create a generic SelectList with this constructor:

    Code Snippet

    SelectList(T entity, Expression<Func<T,object>> field1, Expression<Func<T,object>> field2)

     

    Then you can use it like this with strong typing:

    Code Snippet

    new SelectList(blog, b=>blog_ID, b=>blog_Description);

     

    You don't even need to create a generic class if you don't want to and mine the corresponding strings from the expression trees above:

    Code Snippet

    static SelectList CreateList<T>(T entity, Expression<Func<T,object>> field1, Expression<Func<T,object>> field2)

    {

        string f1name = (field1.Body as MemberExpression).Member.Name;
        string f2name = (field2.Body as MemberExpression).Member.Name;

        return new SelectList(entity, f1name, f2name);
    }

     

    SelectList.Create(blog, b=>blog_ID, b=>blog_Description);

    Although this latter aproach will only throw a runtime exception if you use different expressions than the intended simple field access.

  • 2008년 7월 5일 토요일 오전 5:59hnchass 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     

    Excellent Solution!!! Thanks.

     

    However, My selectlist's original data type is a List and the code is as follows :-

     

    ViewData["Blog_TypeList"] = WebUtility.CreateList (blog_TypeList.OrderBy(c => c.Seq), c => c.First().Blog_Type_ID, c => c.First().Description);

     

    Could I remove the First() from the code?


           

  • 2008년 7월 5일 토요일 오전 7:59Greg Bachraty 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     

    You can change the "T entity" parameter to "IEnumerable<T> entities". The compiler will still deduce the generic parameter for the function.

  • 2008년 7월 5일 토요일 오전 9:03hnchass 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     

    Thanks. Cool. It works.

     

    Besides, just curious, for this solution:-

     

    Code Snippet

    SelectList(T entity, Expression<Func<T,object>> field1, Expression<Func<T,object>> field2)

     

    Then you can use it like this with strong typing:

    Code Snippet

    new SelectList(blog, b=>blog_ID, b=>blog_Description);

     

     
    Where do I put the constructor, modify the source code?
     
     
  • 2009년 7월 3일 금요일 오전 4:29Shimmy Weitzhandler 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     코드 있음
            public static string[] GetIdField<TEntity>() where TEntity : EntityObject
            {
                IEnumerable<string> ids = from p in typeof(TEntity).GetProperties()
                                          where (from a in p.GetCustomAttributes(false)
                                                 where a is EdmScalarPropertyAttribute &&
                                                 ((EdmScalarPropertyAttribute)a).EntityKeyProperty
                                                 select true).FirstOrDefault()
                                          select p.Name;
    
                return ids.ToArray();
            }

    Shimmy