1

I've just started to trying to build some test ASP.Net Web API app, and got a problem:

I have models as:

public class Asset
{
    public int Id { get; set; }
    [ForeignKey("AssetType")]
    public int AssetTypeId { get; set; }
    public AssetType AssetType { get; set; }
}
public class AssetType
{
    public int Id { get; set; }
    public string Name { get; set; }
}

and trying to get all records from db via

    public IEnumerable<Asset> GetAssets()
    {
        return db.Assets.AsEnumerable();
    }

I get some strange results (atleast that's strange for me). Instead of expanding AssetType - I get nil's:

<Asset>
<AssetTypeId>1</AssetTypeId>
<Id>1</Id>
<AssetType i:nil="true"/>
</Asset>

I've checked my db - it contains correct IDs in both AssetTypeId and AssetType fields, pointing to correct asset type. The only way I've found to get fields expanded - is by changing GetAssets to:

    public HttpResponseMessage GetAssets()
    {
        return Request.CreateResponse(HttpStatusCode.OK, db.Assets.Include("Type").ToList());
    }

But I feel I'm very wrong, because in reality I have dozens of such 'complex' fields with some of them nested, and adding them via ".Include("Type")" - is wrong.

So the question is - where I've made an error? How can I get my data correctly?

soralex
  • 129
  • 1
  • 10
  • Note I believe you could merely use `public virtual AssetType AssetType { get; set; }` but you need to be careful about the N+1 problem with ORMs http://stackoverflow.com/questions/97197/what-is-the-n1-selects-issue I personally detest lazy loading in ORMs. – Chris Marisic Oct 17 '14 at 18:25

1 Answers1

2

This is because of lazy loading.

Lazy loading is a concept where we delay the loading of the object until the point where we need it. Putting in simple words, on demand object loading rather than loading objects unnecessarily.

When you did .include, it actually loaded that data and you are able to get it.

There is no default configuration for eager loading. You must always define Include or create some reusable method which will wrap adding include.

Entity Framework 4.1 default eager loading

Community
  • 1
  • 1
Arindam Nayak
  • 7,346
  • 4
  • 32
  • 48
  • I don't think this answers the OP's question, I believe he is looking for how to specify "eagerly serialize/materialize my object graph" – Chris Marisic Oct 17 '14 at 18:19
  • 1
    AH now i understand. The OP isn't using the virtual keyword for EF to dynamic proxy his AssetType property so it doesn't exist at serialization time. When the OP specified `Include` that initially hydrated the full object. – Chris Marisic Oct 17 '14 at 18:24
  • 1
    Well, thanks @ArindamNayak. When I've tried to add virtual keyword - asp.net continued complaining at me, so I'll use lots of includes then. – soralex Oct 17 '14 at 18:59
  • @soralex, have a look on the URL ( last line of my post), that has some helpful method. – Arindam Nayak Oct 17 '14 at 19:02