Raza Jamil
Raza Jamil

Reputation: 274

NHibernate returning results from Web API

I'm using Nhibernate to fetch a collection which has lazy loaded properties but am having trouble returning it as the Serializer tries to serialize the lazy property after the Nhibernate Session is closed. So is there a way to tell NHibernate to give me a true list in which if there were unloaded lazy collections that it would just leave them empty?

For example

IEnumerable<Store> stores = StoreService.GetList(1, 2);

Store has a one-to-many mapping with StockItems which is set to lazy load which then causes the serialization error. I tried

List<Store> stores_r = stores.ToList();

but I get the same thing. Is there something that will traverses through the list and fetches one-to-one relations and ignores one-to-many lazy loading and return a finished list?

Thanks

EDIT:Solution I've tried but still not working

public class NHibernateContractResolver: DefaultContractResolver
    {
    protected override JsonContract CreateContract(Type objectType)
    {
        if (typeof(NHibernate.Proxy.INHibernateProxy).IsAssignableFrom(objectType) || typeof(NHibernate.Proxy.ILazyInitializer).IsAssignableFrom(objectType))
        {
            var oType = objectType.GetInterfaces().FirstOrDefault(i => i.FullName.StartsWith("Navace.Models"));
            return oType != null ? base.CreateContract(oType) : base.CreateContract(objectType.BaseType);
        }

        return base.CreateContract(objectType);
    }

    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
        if (typeof(NHibernate.Proxy.INHibernateProxy).IsAssignableFrom(objectType))
        {
            return base.GetSerializableMembers(objectType.BaseType);
        }
        else
        {
            return base.GetSerializableMembers(objectType);
        }
    }
}

Try to manually serialize so I can use what's happening

IEnumerable<Store> stores = StoreService.GetList(1, 2);

Store> storess = stores.ToList();

JsonSerializer sr = new JsonSerializer
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                ContractResolver = new NHibernateContractResolver(),
                NullValueHandling = NullValueHandling.Ignore,
            };

StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new Newtonsoft.Json.JsonTextWriter(stringWriter);
sr.Serialize(jsonWriter, storess);

string res = stringWriter.ToString();

The error I get is

Outer exception : Error getting value from 'datedcost' on 'PartProxy'.

Inner exception: No row with the given identifier exists[Navace.Models.Part#0]

Upvotes: 0

Views: 396

Answers (1)

Jamie Ide
Jamie Ide

Reputation: 49291

My recommendation is to return view models instead of domain models. It's confusing to return an empty collection property when it may have data. By converting the domain model to a view model (using LINQ Select or AutoMapper), the serializer will only touch (and attempt to lazy load) the properties in the view model.

Upvotes: 1

Related Questions