0

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]

Raza Jamil
  • 264
  • 1
  • 3
  • 12
  • Why don't you just ignore serialization for that property? – Onur Gumus Nov 13 '16 at 04:29
  • I've tried the GetSerializableMembers approach from [this](http://stackoverflow.com/questions/286721/json-net-and-nhibernate-lazy-loading-of-collections/5926718#5926718) link. If I return null on Proxy matches it throws null reference exception and if I return base type it says no rows with Type#0 found. – Raza Jamil Nov 13 '16 at 04:35
  • NHibernateUtil (https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/NHibernateUtil.cs) has some useful methods that might help. – David Osborne Nov 14 '16 at 08:56

1 Answers1

1

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.

Jamie Ide
  • 48,427
  • 16
  • 81
  • 117