我有Queryable<Foo>
和List<Bar>
。我已经能够使用LINQ映射哪些书与哪些作者相关。
我想使用Bar
的值并动态地向Foo
对象添加属性,如下所示,显然将类型更改为object
或dynamic
。< / p>
这是否可以使用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; }
}
答案 0 :(得分:2)
您无法动态地向类添加属性。我可以看到几种方法可以获得理想的结果。
最简单的方法是修改你的课程
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
答案 1 :(得分:1)
您是否尝试过使用匿名类型?
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时都不需要更改,并且会干净地序列化。
答案 2 :(得分:0)
使用动态属性,使用OData4中提供的“开放类型”解决了我的问题。
public IDictionary<string, object> DynamicProperties { get; set; }
通过创建DynamicProperties属性,我可以设置并获取我试图通过LINQ动态添加的成员。
Reference documentation on open types in C#
由于我没有通过LINQ解决问题,我不会选择我的答案作为接受的答案,但我认为它可能对将来的人有用。如果有人使用LINQ发布解决原始问题的答案,我会接受它。
答案 3 :(得分:0)
如果您希望向对象动态添加属性,这可能是一个解决方案。
这对我有用,我也有一个担忧,那就是那些具有许多属性的领域对象发生了什么,该对象中任何更改的可维护性都是荒谬的,我设法用 LINQ-ExpandObject-Reflection 构建实现,这有助于使对象保持动态,并且仅添加视图逻辑所需的其他属性。
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();