简单/简洁的方法来创建包含已定义类的所有属性的新匿名类型,以及一些其他字段?

时间:2018-02-08 16:40:33

标签: c# .net asp.net-mvc vb.net linq

说我有一个简单的POCO课程:

Public Class Person

    Public Property Id As Integer

    Public Property Name As String

    Public Property Age As Integer

End Class

我想以JSON格式返回这些对象的列表,但每个对象也需要一个UUID,因此使用LINQ Select语句,我创建了一个新的anoynmous类型,其中包含Person的所有属性,以及addtional UUID字段。我想知道是否有更短的方法来创建这样的类型。例如:

Public Function GetPeople() As JsonResult

    Dim people = _personRepository.GetAllPeople()

    ' Shorter way to write the statement below?
    ' EG something like "people.Select(Function(x) x.Merge(New With { .uuid = Guid.NewGuid() })"

    Return Json(people.Select(Function(x) New With {
         x.Id,
         x.Name,
         x.Age,
         .uuid = Guid.NewGuid().ToString()
    }, JsonRequestBehavior.AllowGet)

 End Function

我对VB或C#中的代码示例很好。

2 个答案:

答案 0 :(得分:2)

使用JSON.net,您可以通过JObject .Add方法动态注入属性。

然后我添加了一个小的静态帮助器方法来将UID添加到您的POCO类。这允许添加动态属性以内联方式完成。

这方面的一个例子 -

//POCO
public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
    //Dummy repo for example
    public static class _personRepository
    {
        public static List<Person> GetAllPeople()
        {
            return new List<Person>();
        }
    }

    class Program
    {   
        //static helper class - accepts a POCO and dynamically adds a property and spits out a JObject
        private static JObject IDPerson(Person person)
        {
            var ret = JObject.FromObject(person);
            ret.Add("UID", Guid.NewGuid().ToString());
            return ret;
        }
        static void Main(string[] args)
        {
            //get the list of people

            var allpeople = _personRepository.GetAllPeople();
            //in line here select a new object from our helper method
            var qry =
                (
                    from person
                    in allpeople
                    select IDPerson(person) //this is the dynamic bit 
                ).ToList();
        }
    }

答案 1 :(得分:0)

您还可以将对象转换为expando并在将其转换为json之前添加任何其他属性

var map = new Func<Person, dynamic>(person =>
{
    var result = person.ToDynamic();
    result.Uuid = Guid.NewGuid();
    return result;
});

var results = persons
    .Select(p => map(p))
    .ToList();

.ToDynamic做什么呢?)

public static dynamic ToDynamic(this object value)
{
    IDictionary<string, object> expando = new ExpandoObject();
    var properties = TypeDescriptor.GetProperties(value.GetType());
    foreach (PropertyDescriptor property in properties)
    {
        expando.Add(property.Name, property.GetValue(value));
    }

    return expando as ExpandoObject;
}