如何使用 LINQ 动态地向对象添加属性



我有一个Queryable<Foo>和一个List<Bar>。我已经能够使用 LINQ 映射哪些书籍与哪些作者相关。

我想使用Bar的值并向Foo对象动态添加属性,如下所示,显然将类型更改为objectdynamic

这在 LINQ 中是否可行,如果是,我该怎么做?

示例期望结果(最终解析为 JSON)

{
    "Id" : 1,
    "Name" : "John Doe",
    "Garden" : 7,
    "Pilot" : 4
}

示例类

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }
}
public class Bar
{
    public string Title { get; set; }
    public int Count { get; set; }
}

不能动态地向类添加属性。我可以看到几种方法,您可能会获得所需的结果。

最简单的方法是将你的类修改为

public class Author
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Book> AuthorBooks { get; set; }
}
public class Book
{
    public string Title { get; set; }
    public string Isbn { get; set; }
}

但是,这会给您的 JSON 结构略有不同

另一种方法是使用 ExpandoObject,前提是您使用的是 .net.4.0 或更高版本。ExpandoObject 允许您添加属性,因为它基于 Dynamic 类。

您可以在此处获取更多信息 https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject/

希望这有帮助

编辑

你可以尝试这样的事情

FooList.ForEach((x) =>
            {
                //Define a new expando
                dynamic NewClass = new ExpandoObject();
                NewClass.Id = x.Id;
                NewClass.Name = x.Name;
                //Get the relating Bar Record
                BarList.Where(b=> b.FooId == x.Id).ToList().ForEach((b) =>
                {
                    NewClass[b.Title] = b.Count;
                });
                //This bit Depends on how you want the Json
                using (TextWriter writer = System.IO.File.CreateText("YourFilepat/Here"))
                {
                    var serializer = new JsonSerializer();
                    serializer.Serialize(writer, NewClass);
                }
            });

JsonSerializer 来自 Newtonsoft.Json

你试过使用匿名类型吗?

var foos = new List<Foo>{
    new Foo{Id = 1, Name = "Grapes of Wrath"},
    new Foo{Id = 2, Name = "Shantaram"}
};
var anonObject = from f in foos
                    select new
                    {
                        Id = f.Id,
                        Name = f.Name,
                        Garden = 6
                    };
var serialized = JsonConvert.SerializeObject(anonObject);
return serialized; //[{"Id":1,"Name":"Grapes of Wrath","Garden":6},
    //{"Id":2,"Name":"Shantaram","Garden":6}]

请注意,匿名类型不能跨越函数边界,因此必须创建动态属性并在同一函数中进行序列化。

或者,您可以像这样创建新类型:

public class FooBar
{
    public Foo Foo { get; set; }
    public List<Bar> Bars { get; set; }
}

而且这家伙可以到处移动,拥有你需要的所有属性,不需要每次你改变Foo或Bar时都改变,并且会干净利落地序列化。

如果您希望将属性动态添加到对象,这可能是一个解决方案。

这就是对我

有用的,我也有一个担忧,那就是那些具有许多属性的域对象发生了什么,对象中任何更改的可维护性都是荒谬的,我设法使用 LINQ - ExpandObject - 反射构建了一个实现,这有助于保持我的对象动态,并且只添加我的视图逻辑所需的其他属性。

var expandedModel = FooList.Select(x =>
                    {
                        dynamic expandObject = new ExpandoObject();
                        expandObject.NewProperty= $"PropertyValue";
                        foreach (var property in x.GetType().GetProperties())
                        {
                            ((IDictionary<string, object>)expandObject).Add(property.Name, property.GetValue(x));
                        }
                        return expandObject;
                    }).ToList();

最新更新