实体框架.嵌套集合查询传递“空”;值“;关于setter方法

本文关键字:框架 关于 setter 方法 查询 集合 实体 嵌套 | 更新日期: 2023-09-27 18:00:28

我有一个"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"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]}]

非常感谢您的帮助。

实体框架.嵌套集合查询传递“空”;值“;关于setter方法

试图在数据库中实现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
}