0

I have a Company class:

public class Company
{
    public int CompanyId { get; set; }
    public string CompanyName { get; set; }
    public int? AnalystId { get; set; }
    public int? ReviewerId { get; set; }
    public virtual Staff Analyst { get; set; }
    public virtual Staff Reviewer { get; set; }
    public virtual ICollection<CompanyFile> Files { get; set; }
}

One of the navigation properties is a CompanyFile, which looks like this:

public class CompanyFile
{

public int CompanyFileId { get; set; }
public Guid FileContentId { get; set; }
public int CompanyId { get; set; }
public virtual Company Company { get; set; }
public string OrigFileName { get; set; }
public byte[] FileContents { get; set; }
}

In the code, there's a method to load the company and its navigation properties that looks like this:

public async Task<Company> GetAsync(int id)
{
    return await Repo
    .Include("Analyst")
    .Include("Reviewer")
    .Include("Files")
    .Where(w => w.CompanyId == id).FirstOrDefaultAsync();
}

That all works as intended, but the problem is that if the FileContents property is large, then it takes a long time to load the Company object. Is there a way to load the CompanyFile navigation property but exclude the FileContents property?

EDIT:

  • There's a link mentioned in the comments, but what the link describes is how ignore a property while creating a single object and not a collection.

  • Then I tried this:


    return await Repo
    .Include("Analyst")
    .Include("Reviewer")
    .Include("Files")
    .Where(w => w.CompanyId == id).
    .AsEnumerable()
    .Select(p => new Company
    {
    p. CompanyId,
    [snip]
    Files = new File {               
        CompanyFileId = p.Files.CompanyFileId,
        FileContentId = p.Files.FileContentId,
        CompanyId = p.Files.FileContentId,
        OrigFileName = p.Files. OrigFileName 
    })

Compiler error: Cannot initialize type "Company" with a collection initializer because it does not implement System.Collections.IEnumerable

  • So I tried this

     Company company = Repo
              .Include("Group")
              .Include("Analyst")
              .Include("Reviewer")
              .Include("Reviews")
              //.Include("Files")
              .Include("Priorities")
              .Where(w => w.CompanyId == id)
              .ToList()
              .FirstOrDefault();
    
    var FileRepo = Context.Set<CompanyFile>();
    var ReviewFiles = FileRepo.Where(f => f.CompanyId == id)
            .Select(t => new CompanyFile   {
                 t.CompanyId,
                 {snip]
                 t.OrigFileName
                  })
                 .ToList();
    

Compile time error: Cannot initialize type CompanyFile with a collection initializer because it does not implement System.Collections.IEnumerable

  • So I changed the last bit to
    var ReviewFiles = FileRepo.Where(f => f.CompanyId == id) 
         .Select(t => new CompanyFile { 
             CompanyId = t.CompanyId,
            [snip] 
            OrigFileName = t.OrigFileName });

// Run-time error: Message = "The entity or complex type 'CompanyFile' cannot be constructed in a LINQ to Entities query."

Duston
  • 1,601
  • 5
  • 13
  • 24
  • Does this work? ```.Include("Files").Ignore(f => f.FileContents)``` Found from here: https://stackoverflow.com/questions/10385248/ignoring-a-class-property-in-entity-framework-4-1-code-first – Garrison Becker Aug 20 '20 at 14:30
  • I don't think that is the right syntax. `.Ignore` is for configuring the entity itself and would remove the ability to save FileContents elsewhere. What you want is some form of projection like [this](https://stackoverflow.com/questions/29449038/select-specific-columns-when-using-include-statement-with-entity-framework). – Steve Greene Aug 21 '20 at 05:13
  • That looks promising, but the example the contained object isn't a collection. So somehow I'd have to come up with a foreach() and build a new collection of anonymous objects? – Duston Sep 21 '20 at 15:36

0 Answers0