我有一个"Driver"模型,具有一对多"Trucks"导航属性。我想用逗号分隔的字符串属性填充一个示例"TruckDriver"模型,该属性包含所有相关的TruckId。
为了无缝地填充这个模型,我实现了一个setter函数,它接收Int32[]数组并将其序列化为String。
我面临的问题是,在尝试使用投影用单个查询填充此模型时,linq-to-entities将一个空集合传递给setter"value"属性。
奇怪的是,如果不尝试处理数据,而只将其分配为IEnumerable,它会很好地工作。如果我先实例化数据,然后执行查询,它也会很好。
示例代码:
正在尝试填充的模型。
public class TruckDriver
{
public String Name { get; set; }
public String Serialized { get { return this._serialized; } }
public IEnumerable<Int32> OriginalArray { get; set; } <--Debug Property to test actual data returned by the query.
private String _serialized;
public IEnumerable<Int32> setSerialized {
set {
this._serialized = String.Join(",", value); <---- value is always an empty collection on the debugger
}
}
}
查询执行
var temp = db.Drivers.Include(d=>d.Trucks);
TruckDriver[] drivers= temp.Select(d => new TruckDriver
{
Name= d.FirstName+" "+d.LastName,
OriginalArray = d.Trucks.Select(r=>r.Id),
setSerialized = d.Trucks.Select(r => r.Id),
}).ToArray();
return drivers;
返回的数据。
[{"Name":"Mark Miller","Serialized":"","OriginalArray":[1,4]},{"Name":"John Smith","Serialized":"","OriginalArray":[2,3]}]
正如你所看到的。"OriginalArray"one_answers"setSerialized"获得完全相同的数据。尽管"OriginalArray"正确地包含多个整数,但"Serialized"是一个空字符串。
如果在执行查询之前实例化所有数据,则模型将正确填充。
查询前实例化。
var temp = db.Drivers.Include(d=>d.Trucks).ToArray();
TruckDriver[] drivers= temp.Select(d => new TruckDriver
{
Name= d.FirstName+" "+d.LastName,
OriginalArray = d.Trucks.Select(r=>r.Id),
setSerialized = d.Trucks.Select(r => r.Id),
}).ToArray();
结果
[{"Name":"Mark Miller","Serialized":"1,4","OriginalArray":[1,4]},{"Name":"John Smith","Serialized":"2,3","OriginalArray":[2,3]}]
值得注意的是,如果我为"OriginalArray"属性编写自己的setter,那么在"set"执行期间,"value"仍然是调试器中的一个空集合,尽管之后会正确填充数据。
public class TruckDriver
{
public String Name { get; set; }
public IEnumerable<Int32> OriginalArray
{
get{
return this._originalArray;
}
set {
this._originalArray = value; //<-- value is still an empty collection
}
}
private IEnumerable<Int32> _originalArray;
}
结果。
[{"Name":"Mark Miller","OriginalArray":[1,4]},{"Name":"John Smith","OriginalArray":[2,3]}]
非常感谢您的帮助。
试图在数据库中实现string.Join()
是行不通的,因为Linq不知道如何将其转换为SQL。您可能会为它编写一个原始SQL查询或存储过程,但我认为您不会从中获得太多好处。基本上,您必须先将它拉入内存,然后创建序列化字符串。您可以使用对匿名对象的投影来限制您提取的数据。
var temp = db.Drivers.Select(d => new
{
Name = d.FirstName + ' ' + d.LastName,
TruckIds = d.Trucks.Select(t => t.Id)
}).ToArray();
var truckDrivers = temp.Select(d => new TruckDriver()
{
Name = d.Name,
setSerialized = TruckIds
}