This project is read-only.

Lite, or not Lite: that's the question.

Sep 5, 2012 at 9:46 AM

Hi guys.

many times I am in doubt whether to use the Lite in my objects.
So I solved it by inserting an extension method in Shop.Entity :

public static class CurrentServer
	public static IServerShop Current { get; set; }

	public static T Value<T>(this Lite<T> lite) where T : class, IIdentifiable
		if (lite.EntityOrNull == null)
			var value = Current.Retrieve(lite.RuntimeType, lite.Id);
		return lite.EntityOrNull;

Later in Shop.Web:

public class ServerShop : ServerBasic, IServerShop
	public ServerShop ()
		Shop.Services.CurrentServer.Current = this;


Finally in Shop.Windows I add this line in "public static bool NewServer()" method:

	Shop.Services.CurrentServer.Current = current;

Now everywere in my application I can use:

string ordEmployee = order.Employee.Value().LastName + ", " + order.Employee.Value().FirstName;

the Lite<Employee> is loaded the first time I call Value() method in a "Lazyness way"

What do you think about that?

Sep 5, 2012 at 1:51 PM
Edited Sep 5, 2012 at 2:23 PM

Hi angabanga!

Your idea is so good that is already implemented :) 

When calling:

   order.Employee.Retrieve().LastName + ", " + order.Employee.Retrieve().FirstName;

exactly the same hapends!  

This is the implementation of Retrieve on the Server class:

public static T Retrieve(this Lite lite) where T : class, IIdentifiable       
 if (lite.EntityOrNull == null)               
 lite.SetEntity((IdentifiableEntity)(IIdentifiable)Return((IBaseServer s)=>s.Retrieve(lite.RuntimeType, lite.Id)));     
  return lite.EntityOrNull;  

In order to get the non-memory behavior, call order.Employee.RetrieveAndForget() instead. 

Hope it helps, 

...and I hope somebody changes this awfull codeplex text editor :S      

Sep 5, 2012 at 3:27 PM

Hi Olmo,

Thanks for the specification because my post is a bit 'ambiguous'.
In fact, the goal I wanted to achieve was to write more Business Logic directly into the entities, which is not possible otherwise.

For example:

public class OrderDN : Entity
    public string GetOrderEmployee()
        return = order.Employee.Value().LastName + ", " + order.Employee.Value().FirstName;
    public SaveOrder()

Sep 5, 2012 at 4:12 PM

Oh, I understand now. 

What you want is to abstract away the fact that you can be on a windows application, so you have to retrieve through the Server class, or on the server, where you use the Database class. 

There are some technical corner cases, like finding Implementations for a PropertyRoute, or finding the ExtensionsQueryTokens for a QueryToken that do exactly this, but for something like Retrieve... I'm not sure.  

Even if Retrieve is comfortable to use, its an slow solution. 

Your feature will make it too easy to make code like: 

   if(order.Provider.Retrieve().Company.Retrieve().Country.Retrieve().IsoCode == "US")

Because doing it the right way, by catching the value in the order, or maiking a query like this:

    order.Provider.InDB(p=>p.Company.Entity.Country.Entity.IsoCode) == "Us" 

will mean too much changes and abstracting the LINQ provider is not a good idea IMO. 

When you do myLite.Retrieve(), is time to reconsider your design:

* Maybe you should make a smaller query instead
* Maybe you should change the relationship to make it non-lite
* Maybe you should select entities instead of lites from a query
* Or in the worst case, maybe just  Retrieve the lite

Is more a pedagogical reason than a technical one. The fact that we make Lite<T> an explicit public type, as opposed to the hidden Linq to SQL EntityRef<T>, is because making it easy creates slow code.  

With Signum Engine, we try to remove all the friction when dealing with the database, but at the same time make abstractions that make clear when you are dealing with the database so you can write performant code.  

Feel free to implement you feature thought, maybe you can resist the temptation :)


Sep 5, 2012 at 4:59 PM

Thank you for your excellent considerations.