1

I use Entity Framework 6.0.0.0, and approach is Database First. I have three tables Client, Account, Doc. One Client has many Docs and Accounts. The relationship is one to many. Client table:

public partial class Client
{
    public Client()
    {
        this.Account = new HashSet<Account>();
        this.Doc = new HashSet<Doc>();
    }

    public int ClientId { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Account> Account { get; set; }
    public virtual ICollection<Doc> Doc { get; set; }
}

AngularJs code snippet to take data from WebApi:

angular.module("app", []).controller("searchController", function ($scope, $http) {

    //Used to get and display the data
    $http.get('/api/Search/').success(function (data) {
        debugger;
        $scope.searchs = data;
        $scope.loading = false;
    })
    .error(function () {
        debugger;
        $scope.error = "An Error has occured while loading posts!";
        $scope.loading = false;
    });
}

Method Get of Web API to take data(it returns NOTHING. There is no clients):

    [HttpGet]
    public IEnumerable<Client> Get()
    {
        private ClientDBEntities db = new ClientDBEntities();
        retutn db.Client.AsEnumerable();// it returns NOTHING. There is no clients

    }

However, $http.get('/api/Search/').success(function (data) called, if I change this method to return IEnumerable<string> :

    [HttpGet]
    public IEnumerable<Client> Get()
    {
        List<string> list = new List<string>(){"1", "2", "3"};
        return list;            
    }

My question is why db.Client.AsEnumerable() returns nothing? I've tried to change this code to:

retutn db.Client.ToList();// it returns all necessary data

However, AngularJS method is calling $http.get('/api/Search/').error(...)

Any help would be greatly appreciated.

What I see in a Watch window of Visual Studio: enter image description here

StepUp
  • 27,357
  • 12
  • 66
  • 120
  • what is the error that you get? – Amit Kumar Ghosh Aug 25 '16 at 09:33
  • @AmitKumarGhosh There are no errors, just it works like it is all okay. I've attached my watch window to see what I get in every query. Thanks. – StepUp Aug 25 '16 at 09:46
  • Looks to me you are trying to return database objects with lazy loading on. This can cause an out of memory exception when you have circular references when deserializing to json. – Serge Bekenkamp Aug 25 '16 at 09:51
  • @SergeBekenkamp Sorry but what do you mean circular references when deserializing to json? – StepUp Aug 25 '16 at 09:55
  • Sorry i meant serializing. But when you return the data from your web api to your angular application the data is serialized to a different format (usually json or xml) if you have a reference from client to account and then from account to client you it will keep trying to serialize that loop until it runs out of memory. Any other combination of references work as well so for example client-> account-> doc -> client would crash it as well. – Serge Bekenkamp Aug 25 '16 at 09:58
  • @SergeBekenkamp you mean that I should delete relationship `one-to many`? – StepUp Aug 25 '16 at 10:00
  • Not necessarily you could start off with disabling lazy loading to check if this is actually the issue. If it is you could select the results into a new object with only the needed data. see http://stackoverflow.com/questions/24022957/entity-framework-how-to-disable-lazy-loading-for-specific-query on how to disable ef lazy loading – Serge Bekenkamp Aug 25 '16 at 10:12
  • @SergeBekenkamp you are cool! Thanks for your help! Post your answer, please, and I'll mark it. Thank you very much!:) – StepUp Aug 25 '16 at 10:21

2 Answers2

1

Looks to me there is an error serializing your object to either xml or json. This is usually caused by a circular reference in your data object. For example your client references account and account references client. if this is the case the serializer will keep serializing the objects until it runs out of memory

to solve this there are a few options.

  1. Only return the data you really need by transforming it into a new object (viewmodel).
  2. Disable lazy loading for your query, this will prevent loading of your account / doc objects for that query see (Entity Framework: How to disable lazy loading for specific query?).
  3. Make the serializer ignore the properties that cause the self referencing loop. (for serializing to json use the attribute [JsonIgnore])
Community
  • 1
  • 1
Serge Bekenkamp
  • 416
  • 4
  • 13
0

Could you try matching the function return value with List data type?

For example:

[HttpGet]
public List<Client> Get()
{
    private ClientDBEntities db = new ClientDBEntities();
    retutn db.Client.ToList();
}

Update Here is a useful link: What's the difference(s) between .ToList(), .AsEnumerable(), AsQueryable()?

Basically, the key part relevant to your case is this:

ToList – which converts an IEnumerable to a List – is often used for this purpose as well. The advantage of using AsEnumerable vs. ToList is that AsEnumerable does not execute the query. AsEnumerable preserves deferred execution and does not build an often useless intermediate list.

On the other hand, when forced execution of a LINQ query is desired, ToList can be a way to do that.

AsQueryable can be used to make an enumerable collection accept expressions in LINQ statements. See here for more details.

This might explain why you're getting an error, consider sticking to List, or trying AsQueryable() and seeing if that works instead of AsEnumerable()

Community
  • 1
  • 1
Keyur PATEL
  • 2,265
  • 1
  • 11
  • 40
  • yeap, I've tried. However, `$http.get('/api/Search/').error(...)` is called. But I would like `$http.get('/api/Search/').success(function (data) {}` to be called. Thanks for a try. – StepUp Aug 25 '16 at 09:35
  • Can you verify that your `ClientDBEntities()` indeed returns something? Maybe you could show that function's code to help me understand the problem. – Keyur PATEL Aug 25 '16 at 09:47
  • please see my attached image to a question. – StepUp Aug 25 '16 at 09:49