Showing posts with label Castle.ActiveRecord. Show all posts
Showing posts with label Castle.ActiveRecord. Show all posts

Wednesday, April 23, 2008

Many to many lazzziii

NHibernate's rock I scratched my head for a few hours looking at this code
DetachedCriteria filter = DetachedCriteria.For(typeof(Project))
.Add(Expression.Eq("ID", pid))
.SetProjection(Projections.Property("Type"));

DetachedCriteria q = DetachedCriteria.For(typeof(List_Output), "op")
.CreateCriteria("ProjectTypes")
.Add(Subqueries.Exists(filter));

return q.GetExecutableCriteria(
holder.CreateSession(typeof(List_Output))
).List();
Wonder why I got so many sql call to the server? the domain objects in the discussion context are Project has a Type and base on selected Type a project can choices a bunch of Outputs.
So Project is belong to a Type [One-to-Many], and Type has many Outputs where Output belong to Many Types [Many-to-Many].

What I found and fix is Lazzzzzzzziiiiiiiiiiiiiiii :))
I forgot to tell Type to load Outputs in a Lazy way and vise versa once that done I got only one YEAH ! I mean ONE sql call to the server to get what I asked for instead of 2 + N (where N is number of relevant Outputs in a Type)

Thanks to DetachedCriteria & the Laziness until next time today magic word is "Lazy = true"

Friday, April 18, 2008

Woh Woh storedprocedure no more ...

Read the title and want to know how to do that? come with me hacking the Castle code base or to be accurate hack NHibernate code base, what you need to bring along? not much but a SubVersion, NAnt, MbUnit and NUnit that sound enough ;)

Enjoy plug & play your database and let the Jedi rise
Happy Friday everyone !

Wednesday, December 05, 2007

IList you have me?

As much as I hate to deal with numerical index I had to cross it one way or the other so be it.
Here is the fact, I am enjoy using Castle.ActiveRecord to wrap my DAL code cuz it simplify thing a lot for me > 80% somehow when it came to not so complex scenario like this one:

I want to allow my customer to list all the products and set the qty they want to order.
If they already order I would like to give them a chance to update qty for the product that they miss in the previous hit.
public IList LoadProductOrderList(int customer_id)
{
IList result;
ISessionFactoryHolder sh =
ActiveRecordMediator.GetSessionFactoryHolder();
ISession session = sh.CreateSession(typeof(AnnualTarget));
try
{
// note: code wrapped for view
string sql = "SELECT p.pid, p.name, o.qty, o.id as order_id
FROM Products p JOIN Orders o
ON p.pid = o.product_id WHERE o.customer_id = :c1
UNION
SELCT pid, name, 0 as qty, 0 order_id FROM Products";

result = session.CreateSQLQuery(sql)
.AddScalar("ID", NHibernateUtil.Int32)
.AddScalar("NAME", NHibernateUtil.String)
.AddScalar("QTY", NHibernateUtil.Int32)
.AddScalar("ORDER_ID", NHibernateUtil.Int32)
.SetInt32("c1", customer_id)
.List();
}
catch (Exception ex)
{
....
}
finally
{
sh.ReleaseSession(session);
}

return result; <- this is an IList ?!!! I don't like to work with it }
As much as I hate, it is a bad idea to pass IList back to the caller object. What is interesting about this code session.CreateSQLQuery(sql) you can tell it to map the result to an Entity by call like this
session.CreateSQLQuery(sql)
.AddEntity(typeof(EntityObjectOfTypeActiveRecord))
.List();
But anyway I have got time to dig what AddEntity would do with the object pass in to me the road a head is a bit dark. Can I have something more simple?

The simple should be:
public IList LoadProductOrderList(int customer_id)
{
IList betterResult = new List();
.....
for(int i = 0; i < curobject =" (object[])" dto =" new" id =" curObject[0];" name =" curObject[1];" qty =" curObject[2];" orderid =" curObject[3];">
Now it much better to work with