Preloading Business Objects over a Web Service

  • Thread starter Thread starter Chris Kennedy
  • Start date Start date
C

Chris Kennedy

I want to serve business objects via a web service. I like the idea, among
other things, of cutting down on round tripping by optionally prefetching
associated objects.

My main concern is how to stop cascading preloading i.e. Customer object
preloads invoices which in turn preload Orders which in turn preloads
Orderlines. Can anyone recommend a way of doing this. Ideally I would like
to be able to easily express e.g. Get a Customer, their Invoices, their
Orders but not Orderlines.

I know this is fairly easy to do with the Entity Framework but I can't use
that. Regards, Chris.
 
Chris said:
I want to serve business objects via a web service. I like the idea, among
other things, of cutting down on round tripping by optionally prefetching
associated objects.

My main concern is how to stop cascading preloading i.e. Customer object
preloads invoices which in turn preload Orders which in turn preloads
Orderlines. Can anyone recommend a way of doing this. Ideally I would like
to be able to easily express e.g. Get a Customer, their Invoices, their
Orders but not Orderlines.

I know this is fairly easy to do with the Entity Framework but I can't use
that. Regards, Chris.

What are you talking about the EF is the way to do it but you can't use
it? So why can't you use EF? And please don't tell me it's because if
you use Link-to-Entity, it's going to comeback with everything and you
don't want everything, because there are ways around that.

So what are you talking about business objects? Are you talking about an
object that has business rules and can persist itself to the database
using properties and methods? Or are you talking Data Transfer Object
(DTO) that just has properties only?

The way you would do this is to use a WCF Web Service using
datacontracts. The objects would be serialized datacontracts on the WCF
Web service interface. An EF Entity is an implicit WCF datacontract.

So if you look a the code for an Entity in the Designer.cs, it will show
the [Serialized] attributes being used for the class and the properties
in the class that makes that class a serialized datacontract, so that
you can make your own serialized datacontract objects.
 
We basically tried using the Entity Framework with ADO.net data services and
had a lot of problems. For the moment all's I want is to have a DAL which
speaks to BLL these BLL objects are served up over a Web Service (the old
type not a WCF). As the object is served over a web service it will just
have properties. I will just pass the object back if I want to update it. So
I guess you would call a DTO object.

All's I want to know is a nice technique/design pattern to optionally eager
load or prefetch child collections i.e. the opposite of the lazy loading
pattern. If I have a deep hierarchy of objects I want to be able to easily
express what is preloaded. To repeat:

My main concern is how to stop cascading preloading i.e. Customer object
preloads invoices which in turn preload Orders which in turn preloads
Orderlines. Can anyone recommend a way of doing this. Ideally I would like
to be able to easily express e.g. Get a Customer, their Invoices, their
Orders but not Orderlines.


Mr. Arnold said:
Chris said:
I want to serve business objects via a web service. I like the idea,
among other things, of cutting down on round tripping by optionally
prefetching associated objects.

My main concern is how to stop cascading preloading i.e. Customer object
preloads invoices which in turn preload Orders which in turn preloads
Orderlines. Can anyone recommend a way of doing this. Ideally I would
like to be able to easily express e.g. Get a Customer, their Invoices,
their Orders but not Orderlines.

I know this is fairly easy to do with the Entity Framework but I can't
use that. Regards, Chris.

What are you talking about the EF is the way to do it but you can't use
it? So why can't you use EF? And please don't tell me it's because if you
use Link-to-Entity, it's going to comeback with everything and you don't
want everything, because there are ways around that.

So what are you talking about business objects? Are you talking about an
object that has business rules and can persist itself to the database
using properties and methods? Or are you talking Data Transfer Object
(DTO) that just has properties only?

The way you would do this is to use a WCF Web Service using datacontracts.
The objects would be serialized datacontracts on the WCF Web service
interface. An EF Entity is an implicit WCF datacontract.

So if you look a the code for an Entity in the Designer.cs, it will show
the [Serialized] attributes being used for the class and the properties in
the class that makes that class a serialized datacontract, so that you can
make your own serialized datacontract objects.
 
Chris said:
We basically tried using the Entity Framework with ADO.net data services and
had a lot of problems.

I found the ADO.Net data services fairly simple to use. I use it in a
read only capacity using Linq-2-Entities to query the Model on certain
entities with data services setting in BLL. The key to it was the
information i found in the link.

http://marlongrech.wordpress.com/category/linq/

Then I rolled my own like this, just test playing before I implemented
the concept into the solution at work, with no problems.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Services.Client;

namespace TestNorthwind
{
public class Shippers
{
public long ShipperID { get; set; }
public string CompanyName { get; set; }
public string Phone { get; set; }

public static IEnumerable<Shippers> GetAllShippers()
{
var siteuri = new
Uri("http://localhost/NorthwindDataService1/Northwind.svc/");
var context = new DataServiceContext(siteuri);

return from s in context.CreateQuery<Shippers>("Shippers")
where s.CompanyName.Contains("Pac")
select s;
}
}
}

I got the returned results from Shippers.GetallShippers().

Then in the calling BLL object that called the Shippers.GetallShippers,
I was able to enumerate over results with a foreach loop creating
ShipperView DTO and pass it back to the UI control using a
List<ShipperView> to bind it to the control's Datasource.

It's a piece of cake.

For the moment all's I want is to have a DAL which
speaks to BLL these BLL objects are served up over a Web Service (the old
type not a WCF). As the object is served over a web service it will just
have properties. I will just pass the object back if I want to update it. So
I guess you would call a DTO object.

All's I want to know is a nice technique/design pattern to optionally eager
load or prefetch child collections i.e. the opposite of the lazy loading
pattern. If I have a deep hierarchy of objects I want to be able to easily
express what is preloaded. To repeat:

My main concern is how to stop cascading preloading i.e. Customer object
preloads invoices which in turn preload Orders which in turn preloads
Orderlines. Can anyone recommend a way of doing this. Ideally I would like
to be able to easily express e.g. Get a Customer, their Invoices, their
Orders but not Orderlines.


It's a piece of cake and you do it like this, rolling your own objects.

[Serializable]
Public Class Customer
{

public properties for Customer

public List<Invoice> Invoices { get; set; }
public List<Order> Orders { get; set; }


You can use Linq-2-Entity, Entity-SQL or SQL Command Object for the Select.

You read for Customer and using a datareader if ESQL or SCO and you
populate Customer.

You read for Invoice and you populate a new Invoice object on each read
of the result set.

And in the read loop, you do Invoices.Add(Invoice).

You read for Order, populate a new Order on each read in the loop and do
Orders.Add(Order).

}

You return Customer all the way back to the BLL via the Web Service method.

Of course Invoice and Order objects would need to use the [Serliazable] too.

It's a piece of cake.
 
Yes that's really easy but the problems we had were to do with the lack
control over SQL generated. We just couldn't optimise the queries
sufficiently and the Entity Framework was a pain with stored procedures.
What I want to do is have business objects populated via Stored Procs all's
I want to know if anyone can offer advice on data patterns for preloading
child collection.

Mr. Arnold said:
Chris said:
We basically tried using the Entity Framework with ADO.net data services
and had a lot of problems.

I found the ADO.Net data services fairly simple to use. I use it in a read
only capacity using Linq-2-Entities to query the Model on certain entities
with data services setting in BLL. The key to it was the information i
found in the link.

http://marlongrech.wordpress.com/category/linq/

Then I rolled my own like this, just test playing before I implemented the
concept into the solution at work, with no problems.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Services.Client;

namespace TestNorthwind
{
public class Shippers
{
public long ShipperID { get; set; }
public string CompanyName { get; set; }
public string Phone { get; set; }

public static IEnumerable<Shippers> GetAllShippers()
{
var siteuri = new
Uri("http://localhost/NorthwindDataService1/Northwind.svc/");
var context = new DataServiceContext(siteuri);

return from s in context.CreateQuery<Shippers>("Shippers")
where s.CompanyName.Contains("Pac")
select s;
}
}
}

I got the returned results from Shippers.GetallShippers().

Then in the calling BLL object that called the Shippers.GetallShippers, I
was able to enumerate over results with a foreach loop creating
ShipperView DTO and pass it back to the UI control using a
List<ShipperView> to bind it to the control's Datasource.

It's a piece of cake.

For the moment all's I want is to have a DAL which speaks to BLL these
BLL objects are served up over a Web Service (the old type not a WCF). As
the object is served over a web service it will just have properties. I
will just pass the object back if I want to update it. So I guess you
would call a DTO object.

All's I want to know is a nice technique/design pattern to optionally
eager load or prefetch child collections i.e. the opposite of the lazy
loading pattern. If I have a deep hierarchy of objects I want to be able
to easily express what is preloaded. To repeat:

My main concern is how to stop cascading preloading i.e. Customer object
preloads invoices which in turn preload Orders which in turn preloads
Orderlines. Can anyone recommend a way of doing this. Ideally I would
like to be able to easily express e.g. Get a Customer, their Invoices,
their Orders but not Orderlines.


It's a piece of cake and you do it like this, rolling your own objects.

[Serializable]
Public Class Customer
{

public properties for Customer

public List<Invoice> Invoices { get; set; }
public List<Order> Orders { get; set; }


You can use Linq-2-Entity, Entity-SQL or SQL Command Object for the
Select.

You read for Customer and using a datareader if ESQL or SCO and you
populate Customer.

You read for Invoice and you populate a new Invoice object on each read of
the result set.

And in the read loop, you do Invoices.Add(Invoice).

You read for Order, populate a new Order on each read in the loop and do
Orders.Add(Order).

}

You return Customer all the way back to the BLL via the Web Service
method.

Of course Invoice and Order objects would need to use the [Serliazable]
too.

It's a piece of cake.
 
Chris said:
Yes that's really easy but the problems we had were to do with the lack
control over SQL generated. We just couldn't optimise the queries
sufficiently and the Entity Framework was a pain with stored procedures.

I found that you don't use eager loading, and you use lazy loading with
link queries with an ADO.NET Data service and the EF. If you start doing
eager loading using a ToList() or one of the other eager loading
commands it slows down a dataservice tremendously.

And although you can use sprocs, the best practice is not to use sprocs
in EF. Maybe they might be used in a limited capacity, but if everything
is all sprocs, then you defeat the purpose virtual model.

Myself, I will not use sprocs period in EF.

Secondly, if one needs *speed* in queries reading entities against the
model, one uses Entity SQL (ESQL) statements, which is like T-SQL
statements, where one has complete control of the statements just like
one has when using T-SQL.
What I want to do is have business objects populated via Stored Procs all's
I want to know if anyone can offer advice on data patterns for preloading
child collection.

If one is not going to use EF, then one uses SQL Command objects using a
sproc if you like with a datareader, reading the data one row at a time,
you instantiate a new business object or DTO that you made-up and
populate it using a datareader.

The objects must be using serialization that turns the object into a XML
serialized object, with XML serialized object or objects in a collection
sent or received by an XML Web service.

That's how you do it. I can't explained it to you any simpler than that.

I am not trying to get smart with you, but you need to read one of
these books. I am not saying that you use CSLA in your solution. I am
saying you use the concepts of CSLA in building business objects and
leverage the concepts into solutions that you develop using BO(s).

You're getting in that book is the patterns and best practices that are
needed to use a business object and business objects in a collection
preloaded.

Again, I am not saying implement CSLA. I am saying understand what is
happening and then leverage the concepts into your own solutions of
creating and using business objects or DTO(s) in a solution.

http://www.lhotka.net/Default.aspx

You can lead the horse to the water, but you can't make the horse drink.
 
I'll give you an example. You can't do aggregates over ADO.net data
services, this is a real deal breaker if you are doing some kind of paged
gridview. If you want to have a SP which returns an integer EF can't handle
it because it isn't an entity. I could go on and on. I spoke directly to the
EF team and these were things that they acknowleged weren't in version 1.
That is why we are avoiding EF and looking at other ORM solutions or rolling
our own. The book you recommended does look really good. I will have a look
at it because I don't really "get" design pattern properly. Cheers for the
advice.

BTW that is what I am doing using SP's into data readers into Business
Objects but I don't think you are reading my question properly (or I am
explaining it poorly). What I want to know is that if you have a deep
hierarchy of objects e.g. Customer to Invoice to Order to OrderLine. When
you instantiate a Customer is there a way of saying Get Customer with
Invoices and Orders but NOT OrderLines. Is there some slick way of doing
this without custom methods that say GetCustomerWithInvoices(). In EF you
use the Include keyword. Is that clearer?
 
Chris said:
I'll give you an example. You can't do aggregates over ADO.net data
services, this is a real deal breaker if you are doing some kind of paged
gridview.


I use the Model View Presenter pattern, which means that a control is
using a DTO between the UI and the presenter on the interface and is
never in contact with the BLL directly. The interface can be a
collection of DTO(s) a public List<DTO> DTOS { set; } on the interface,
which can use a Session variable if need be up at the UI.

The code to access the Model via an ADO.NET data service is in the BLL.
The Linq query is only to pull the entities by conditions using the
dataservice. I get the query back where I populate a collection of
DTO(s) using List<DTO> and give it back to the UI on the interface
List<DTO> DTOS.

So, under that implementation, I don't see why you couldn't use a
Linq-2-Object aggregate query against the DTOS, as an example, with DTOS
used as the binding datasource of a gridview.

If you want to have a SP which returns an integer EF can't handle
it because it isn't an entity. I could go on and on.

I don't use sprocs period there is no need to use sprocs, IMO, even
though they can be used with EF.
I spoke directly to the
EF team and these were things that they acknowleged weren't in version 1.
That is why we are avoiding EF and looking at other ORM solutions or rolling
our own. The book you recommended does look really good. I will have a look
at it because I don't really "get" design pattern properly. Cheers for the
advice.

Yes, in this case you would roll your own and can still use ADO.NET Data
services if you think outside of the box. And that CSLA book the CSLA
2003 version I read back several years ago and implemented the CSLA
framework and the project that use CSLA in a learning capacity on my
home machine kicked down the door of what object oriented programming
was about. It started making me think outside the box as to just what
one can do with objects.
BTW that is what I am doing using SP's into data readers into Business
Objects but I don't think you are reading my question properly (or I am
explaining it poorly). What I want to know is that if you have a deep
hierarchy of objects e.g. Customer to Invoice to Order to OrderLine. When
you instantiate a Customer is there a way of saying Get Customer with
Invoices and Orders but NOT OrderLines. Is there some slick way of doing
this without custom methods that say GetCustomerWithInvoices(). In EF you
use the Include keyword. Is that clearer?

I don't know who you are talking about. Are you talking ADO.NET SQL
Command objects or are you talking ADO.NET Entity Framework with using
sprocs?

If it were me doing this, I wouldn't use Linq-to-Entity with sproc period.

I would be using Entity-SQL (ESQL) using a Select statement against the
model for the entity wanted, just like you can do it with an ADO.NET SQL
Command object and T-SQL statements whether or not you're using inline
T-SQL or T-SQL in a sproc.

In this case, I would be using inline ESQL statements.

I would use an ESQL Database reader which is not unlike using a
System.Data datareader to read the returned set of entities.

While in the ESQL database reader loop on the results of returned
entities like Entity.Customer only, then I would instantiate a new
Entity.Customer and populate the Entity.Customer from like fields of the
ESQL Entity resultset for Customer Entities.

And I would return Entity.Customer (an object) populated. Do you understand?

If I were doing the above for Entity.Invoices off of the model using
ESQL, then I would be doing it and returning a List<t> or
List<Entity.Invoices>.

Do you understand? It's OOPs. And an Entity is an object, and it can be
instantiated new as an object and populated individually, not related.

I don't know that you can exclude an entity on a one-to-many using
Linq-to-Entity, other than, removing the link on the EDM graphical IDE
between the parent to the child.

Maybe you need to get this book too that shows examples of using ESQL.

http://www.apress.com/book/view/1590597893

Your biggest problem I think for you is that you don't fully understand
object oriented programming. And again not trying to be smart here, but
most don't know OOPs.
 
Chris said:
BTW that is what I am doing using SP's into data readers into Business
Objects but I don't think you are reading my question properly (or I am
explaining it poorly). What I want to know is that if you have a deep
hierarchy of objects e.g. Customer to Invoice to Order to OrderLine. When
you instantiate a Customer is there a way of saying Get Customer with
Invoices and Orders but NOT OrderLines. Is there some slick way of doing
this without custom methods that say GetCustomerWithInvoices(). In EF you
use the Include keyword. Is that clearer?

Oh, one other thing here. If I was using a sproc, then the sproc would a
have 3 individual Selects -- no inner joins.

Select on Customer using its primary-key

Select on Invoices using the foreign-key of Customer on the Invoices.

Select on Order using its foreign-key into Orders.

Three selects used in the sproc with 3 resultsets coming out of the sproc

datareader reading and building the Customer object.

resultset.movenext

datareader reading and building Invoice objects placed in a collection
held within the Customer object.

resultset.movenext.

datareader reading and building Order objects placed in a collection
held within the Customer object.


One method and the method making on call to the database

It would be done in my own rolled Customer object.

Customer object would contain its data and it would contain both
collections, and I would address the Customer.Invoices and
Customer.Orders through Customer.


That was learned by reading the CSLA book and putting the sample
projects together.
 
Back
Top