【问题标题】:List contains one object why?为什么列表包含一个对象?
【发布时间】:2013-05-12 14:28:00
【问题描述】:

我有一个问题,其中包含列表属性的对象包含 1 个项目,它不应该(它应该是空的)。

Station 类包含一个边列表(List Edges)。 Edge 类有一个 EndStation,它的类型是 Station。

问题是,在从 GetEdgesByStartStation() 返回 IQueryable 后,每个 Edge 上的 EndStation 都包含一个不为空的边列表(List Edges)(应该如此)。 列表中的项目是它自己的 Station (edge.EndStation)。我试图在下面的代码中用 cmets 来说明它

public IQueryable<Edge> GetEdgesByStartStation(Station station)
{
    var edges = db.Edges.Where(x => x.StartStationId.Equals(station.ID));
    foreach (var edge in edges)
    {
        edge.EndStation = db.Stations.FirstOrDefault(x => x.ID.Equals(edge.EndStationId)); 
        //Here the edge.EndStation.Edges would contain 1 item, edge.EndStation 
        //eg. edge.EndStation = "Miami", edge.EndStation.Edges = { "Miami" }
    }

    return edges;
}

我希望这段代码做的是将所有的 Station 边缘传递给方法。对于每条边,将 EndStation 与一个空的边列表连接起来。

站类:

public partial class Station
{
    public Station()
    {
        this.Reservations = new List<Reservation>();
        this.StationMaintenances = new List<StationMaintenance>();
    }

    [DataMember]
    //[JsonConverter(typeof(Int32))] 
    public int ID { get; set; }
    [DataMember]
    //[JsonConverter(typeof(Int32))] 
    public int TypeId { get; set; }
    [DataMember]
    public string Title { get; set; }
    [DataMember]
    public string Description { get; set; }
    [DataMember]
    public decimal StationLat { get; set; }
    [DataMember]
    public decimal StationLong { get; set; }
    [DataMember]
    public bool IsOperational { get; set; }
    [DataMember]
    public bool IsActive { get; set; }
    [DataMember]
    public DateTime CreatedDate { get; set; }
    [DataMember]
    public virtual BatteryStorage BatteryStorages { get; set; }
    [DataMember]
    public virtual List<Reservation> Reservations { get; set; }
    [DataMember]
    public virtual List<StationMaintenance> StationMaintenances { get; set; }
    [DataMember]
    public virtual List<Edge> Edges { get; set; }
    [DataMember]
    public virtual StationType StationType { get; set; }
}

边缘类:

public partial class Edge
{
    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public int StartStationId { get; set; }
    [DataMember]
    public int EndStationId { get; set; }
    [DataMember]
    public virtual Station EndStation { get; set; }
    [DataMember]
    public decimal Distance { get; set; }
    [DataMember]
    public decimal Time { get; set; }
    [DataMember]
    public bool IsActive { get; set; }

}

这怎么可能?

【问题讨论】:

  • 您需要提供更多信息。首先,最好在问题中添加一个完全可编译和可执行的代码示例。如果你不能这样做(例如,你可能需要一个数据库),至少提供所有代码 in 问题。我的意思是你应该从 github 项目中添加类,并将它们修剪成与这个问题相关的内容。接下来,你说“它不应该”。问题是,它应该包含什么?零?很多?
  • 为什么它不能容纳一个项目?此错误(如果有)可能与发布的代码无关。
  • 或者可能在数据库关系中。
  • 如果我没看错 - 这是 EF 所做的(自动填写) - 这是关系的另一端 - 每个 EndStation 通过添加到站点列表中 - 自动具有“一个” Edge' 在对面的导航属性中。这就是困扰你的事情吗?
  • 这就是所谓的relationship fixupStation EndStationList&lt;Edge&gt; Edges 位于同一关系的相反两侧。当从 Db (edge.EndStation = ...) 中具体化对象时,EF 会发现对面是您在内存中已经拥有的“边缘”——因此无论您喜欢与否,它都会进行修复并填充它。 - 您应该在此处查看此答案以获取一些详细信息LazyLoadingEnabled setting doesn't seem to work in EF 5

标签: c# entity-framework collections


【解决方案1】:

这就是relationship fixup

Station EndStationList&lt;Edge&gt; Edges 位于同一关系的对立面。
当从 Db (edge.EndStation = ... 行)具体化对象时,EF 发现对面是您在内存中已经拥有的“边缘” - 所以它会进行修复并填充它,无论您是否喜欢它.

您应该在此处查看此答案以获取一些详细信息LazyLoadingEnabled setting doesn't seem to work in EF 5

正如@Slauma 提到的,我认为没有办法禁用它 - 我猜两者都填充是合乎逻辑的(如果不需要从 Db 额外加载)。

【讨论】:

  • 好的,所以我从列表中删除边缘的唯一选择是手动覆盖或清除对象列表?
  • @NSGaga:您现在可以删除问题下的评论。尤其是乔治斯托克会很高兴:) meta.stackexchange.com/questions/180325/…
  • @KLIM8D 我认为您不应该尝试手动清除它(这也会有效地影响您的另一方,这是您不想要的)。该列表是您如何建立关系的逻辑结果。也许你实际上需要并且希望你的关系有点不同,比如有一个“默认”或主站 - 和边缘单独列出 - 你应该考虑一下我猜
  • @KLIM8D:这可能很危险,具体取决于您打算如何处理加载的数据。如果你使用只读数据(你应该使用AsNoTracking() 以提高性能),即在加载它们后处理上下文,你可以安全地清除列表。但是,如果您想在加载数据的同一上下文中应用一些更改,然后稍后调用SaveChanges 清除列表或从列表中删除项目将被检测为关系更改,并且此更改将写入数据库。
  • @NSGaga 我似乎找不到任何其他方式来处理这种关系,它用于寻路(星形算法),因此我需要连接 2 个顶点(站)之间的边,但我会考虑的谢谢。
猜你喜欢
  • 2014-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多