Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 如何加载所有相关EF实体以准备序列化_Entity Framework_Serialization_Lazy Loading_Eager Loading - Fatal编程技术网

Entity framework 如何加载所有相关EF实体以准备序列化

Entity framework 如何加载所有相关EF实体以准备序列化,entity-framework,serialization,lazy-loading,eager-loading,Entity Framework,Serialization,Lazy Loading,Eager Loading,有人能告诉我如何(优雅地)加载所有相关的实体对象以准备序列化到磁盘吗 我有一个会议。一个会话可以有多个录制,这些录制位于Recordings表中。此外,每个录制可以有多个RecordedFiles,它们位于RecordedFiles表中 EF类如下所示(为简单起见缩写): [可序列化] 公开部分课堂 { 公开会议() { this.Notes=new HashSet(); this.Recordings=newhashset(); } public System.Guid SessionGUID

有人能告诉我如何(优雅地)加载所有相关的实体对象以准备序列化到磁盘吗

我有一个会议。一个会话可以有多个录制,这些录制位于Recordings表中。此外,每个录制可以有多个RecordedFiles,它们位于RecordedFiles表中

EF类如下所示(为简单起见缩写):

[可序列化]
公开部分课堂
{
公开会议()
{
this.Notes=new HashSet();
this.Recordings=newhashset();
}
public System.Guid SessionGUID{get;set;}
public int SessionNum{get;set;}
公共虚拟ICollection注释{get;set;}
公共虚拟ICollection录制{get;set;}
}
[可序列化]
公开部分课堂录音
{
公开录音
{
this.RecordedFiles=new HashSet();
this.ProcessedFiles=new HashSet();
}
公共系统.Guid记录Guid{get;set;}
public int RecordingNumber{get;set;}
public System.Guid SessionGUID{get;set;}
公共虚拟ICollection ProcessedFiles{get;set;}
公共虚拟ICollection RecordedFiles{get;set;}
公共虚拟会话会话{get;set;}
}
最初,我使用的是延迟加载,通过反复试验,我发现我无法序列化所有内容,除非在序列化之前碰巧在调试器中展开集合。这是有意义的:通过延迟加载,实体在需要时才会被拉出。但很明显,我不能总是单步通过调试器来执行此操作!我的下一个想法是使用“急切加载”。例如,见。但是如果你看这个,你会发现你需要有“include”语句。我相信我必须有多个include语句(见:)来涵盖会话的不同分支(录音和笔记)。情况甚至比我所展示的更糟:有多个分支在会议结束后出现,它们比我所说的更深。也就是说,一个会话可能有一组录制,而这些录制又有一组RecordedFile,而RecordedFile又有一组RecordedFile,等等

如果我不得不写一些丑陋的表达,比如: Session Session=context.Sessions.Include(“Recordings.RecordedFiles”).Include(“Recordings.ProcessedFiles”).Include(“Equipment.stereodevice”).Include(“Notes”).Where(p=>p.GUID===#####)FirstOrDefault

我会的。但我猜有一种优雅的方式可以说,“加载与给定会话相关的所有实体”。有人能启发我吗?请注意,在上面的怪物中,我同时包含了“Recordings.RecordedFiles”和“Recordings.ProcessedFiles”。也就是说,会话有一组录音。每个录制都有一个RecordedFiles和ProcessedFiles的集合。最好说“包括录音{所有子集合}”

谢谢

戴夫


编辑:我应该指出,避免使用多个“包含”的另一个原因是,如果数据库发生更改(例如,在Recordings下有另一个表或集合),代码将不得不重写。这可能很难跟踪。

恐怕没有内置的方法来完成您想要的操作。您可以使用反射做一些事情,在反射中枚举所有属性并自己加载它们。如下所示:


还有第三种选择:显式加载。感谢Jeroen,我看到了第三种选择。但是,我再次无法看到所有相关实体。在编写原始问题后,我找到了第四种方法:使用存储过程。至少攻击性代码会隐藏在一个地方,并且更容易更改。而且它是这会带来更好的性能。感谢Matt的想法。我阅读了你的链接并尝试了你的示例代码。不幸的是,我遇到了与上一个评论者(user1265146)相同的问题。也就是说,我得到了“System.ArgumentException”,并显示消息:“类型“People”上的属性“RowVersion”不是导航属性。引用和收集方法只能与导航属性一起使用。使用Property或ComplexProperty方法Hey Dave,我已更新了链接上的脚本,该脚本应能处理这些非dbreference对象。我最终使用了所有难看的Include语句,因为(1)我时间紧迫,(2)我觉得我没有完全理解您的代码。希望我能有机会重温一下,所以我很感谢你花时间更新你的脚本。干杯没问题,如果你决定看一看,需要一些理解它的指针,就给我一个叫喊!
[Serializable]
public partial class Session
{
    public Session()
    {
       this.Notes = new HashSet<Note>();
        this.Recordings = new HashSet<Recording>();
    }

    public System.Guid SessionGUID { get; set; }
     public int SessionNum { get; set; }
    public virtual ICollection<Note> Notes { get; set; }
   public virtual ICollection<Recording> Recordings { get; set; }
}

[Serializable]
public partial class Recording
{
    public Recording()
    {
        this.RecordedFiles = new HashSet<RecordedFile>();
         this.ProcessedFiles = new HashSet<ProcessedFile>();
    }

    public System.Guid RecordingGUID { get; set; }
    public int RecordingNumber { get; set; }
    public System.Guid SessionGUID { get; set; }
     public virtual ICollection<ProcessedFile> ProcessedFiles { get; set; }   
    public virtual ICollection<RecordedFile> RecordedFiles { get; set; }
    public virtual Session Session { get; set; }
   }