我有一个Queryable<Foo>
和一个List<Bar>
。我已经能够使用 LINQ 映射哪些书籍与哪些作者相关。
我想使用Bar
的值并向Foo
对象动态添加属性,如下所示,显然将类型更改为object
或dynamic
。
这在 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();