簡體   English   中英

實體框架:跳過幾列或從相關實體中選擇為空

[英]Entity Framework: Skip few columns or select as null from related entities

我有三個實體如下

public partial class Ticket
{
    public int TicketId { get; set; }
    ...
    public virtual ICollection<TicketComment> TicketComments { get; set; }
}

public partial class TicketComment
{
    public int CommentId { get; set; }
    public int TicketId { get; set; }
    ...
    public virtual ICollection<CommentAttachment> CommentAttachments { get; set; }
    public virtual Ticket Ticket { get; set; }
}

public partial class CommentAttachment
{
    public int FileId { get; set; }
    public int CommentID { get; set; }
    public string FileName { get; set; }
    public int FileSize { get; set; }
    public byte[] FileContents { get; set; }  // holds large data

    public virtual TicketComment TicketComment { get; set; }
}

這里每張票可以有多個注釋,每個注釋可以有1或0個附件。 我試圖用以下代碼急切加載給定票證的所有相關實體

var query = context.Tickets.Where(t => t.TicketId == ticketid)
             .Include(t => t.TicketComments.Select(c => c.CommentAttachments));

它正確地完成了工作。

唯一的問題是,它還加載了byte[] FileContents ,它通常具有相當大的數據。 我想避免它。

有什么辦法我可以為FileContents選擇NULL或者完全跳過這一列?

我試過跟隨

var query = context.Tickets.Where(t => t.TicketId == ticketid)
            .Include(t => t.TicketComments
                .Select(c => c.CommentAttachments
                    .Select(ca => new CommentAttachment()
                    {
                        CommentID = ca.CommentID,
                        FileContents = null,
                        FileId = ca.FileId,
                        FileName = ca.FileName,
                        FileSize = ca.FileSize
                    })));

但它給出了錯誤

The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties. Parameter name: path

有什么想法可以避免加載FileContents列?

public partial class CommentAttachment
{
    public int FileId { get; set; }
    public int CommentID { get; set; }
    public string FileName { get; set; }
    public int FileSize { get; set; }

    public virtual TicketComment TicketComment { get; set; }
}

public class FileContent
{
     FileContentId {get;set;}
     public int FileId { get; set; } // HERE IS THE FORGEIN KEY YOU HAVE TO UPDATE IT manually
     public byte[] FileContents { get; set; }  // holds large data
}

通過這種方式,您只需要擁有CommentAttachment Id即可加載FileContent,並且您可以隨時包含它。

返回null getter但允許setter在EF 6.0和OData v4中運行。

我遇到過同樣的問題。 接受的答案肯定是一個可行的選擇,我今天幾乎實現了它,但我希望在代碼中執行任務。 我的模型略有不同,因為byte[] Timestamp列可用。 如果以后可以幫助某人,則發布此解決方法。

對於我的情況, byte[] FileContents用作目錄存儲庫的備份,如果前端因各種原因被清除,我們使用數據庫來重建目錄結構和文件內容。 基本上我們只有POST / SET FileContents,我們從未通過前端程序讀取它。

public partial class CommentAttachment
{
     //required for overriding get/set auto-property
     private byte[] _FileContents; 

     public int FileId { get; set; }
     public int CommentID { get; set; }
     public string FileName { get; set; }
     public int FileSize { get; set; }
     public byte[] FileContents 
     { 
          get
          {
               return Timestamp != null ? null : _FileContents;
          } 
          set
          {
               _FileContents = value;
          }
     }  // holds large data

     public virtual TicketComment TicketComment { get; set; }
     //Concurrency Token - triggered on create or update
     public byte[] Timestamp { get; set; }
 }

上面允許我們的數據庫表保持不變,只有EF POCO改變了。 創建CommentAttachment記錄時, Timestamp字段為null /不存在,因為它是由數據庫觸發的; 這允許填充_FileContents。 選擇記錄時,會使用數據庫中的值填充Timestamp ,因此將FileContents設置為null以避免查詢大型數據集。

當應用於OData v4時,PUT / PATCH / POST也可以正常使用此方法,因為它不是為了插入/更新而傳遞Timestamp ,因為它是數據庫觸發的填充。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM