silverlight 4 with multiple domain service classes - silverlight-4.0

In my SL Application I have multiple DomainService Classes which deals with the specific entities. Now I need to call upon a method from DomainService Class 1 in Class 2. How do I do that?
e.g
Product entity is handled in Class2 whereas the Workflow entities are handled by Class 1.
I have created a custom class which has properties from entities. Now I need to access the WorkflowStatus fields from one of Workflow entities for the relevant product in Class 2.
How can I call the Class1 method (GetLatestStatus(int productID)) from Class2's method GetProudctwithStatus()
public IList<ProductVS> GetProductsWithStatus()
{
var result = (from p in this.ObjectContext.Products
select new ProductVS
{
ProductID = p.ProductID,
Code = p.Code,
// ???
WFStatus = **Class1.GetLatestStatus(p.ProductID)**
}).ToList();
return result;
}
Any response would be much appreciated

If this is a common task I would instead create an operation on the Server which returned the data that you need. You can do this by creating the method and utilizing the [Invoke] attribute.
Otherwise you need to call two methods, both of which are asynchronous. If this was my project I would make the first call, then send a list of ProductID's to the server to retrieve the WorkFlow status. Otherwise you would be making N number of service calls to the server (one per each entity returned from the server) which is bad.

Related

OOP web application class design

I'm trying to build a web application using OOP.
In my application i have Courses and Subscribers.
Each Course can have multiple Subscribers (1-N relation).
Now i need to perform some operations on Courses (check some expire dates and perform actions on it's subcribers, send some emails to admins) and, after performing them, perform other operations on each Subscriber (send emails).
I created a Course class and a Subscriber class.
Course class contain course data like title, dates, current status and a group of Subscriber objects (those who partecipate to it).
Subscriber class contains name, last name, subscription status etc.
I have a problem.
My Course class need to be aware of it's Subscribers.
My Subscriber class need to be aware of the Course it belongs to (to exctract data like title, dates...) and aware of how much subscribers are and their status.
How can i redesign my class structure to solve this?
I was thinking about using some kind of observer pattern...
PS. i'm using PHP
No need for a special design pattern, this is a normal bidirectional association. I get from your description that any subscriber only subscribes to one course, otherwise there should be two classes Student and CourseSubscription instead.
How to simply construct the association in PHP:
class Course
{
/**
* #var Subscriber[]
*/
protected $subscribers = array();
public function addSubscriber(Subscriber $subscriber)
{
$this->subscribers[] = $subscriber;
}
}
class Subscriber
{
/**
* #var Course
*/
protected $course;
public function __construct(Course $course, $name, ...)
{
$this->course = $course;
$course->addSubscriber($this);
$this->name = $name;
...
}
}
A subscriber object can only exist with a course, so you pass the course as parameter to the constructor. There the newly created subscriber registers itself for the course.
it sounds like an observer pattern till the point you said
and aware of how much subscribers are and their status.
You need a version of Observer Pattern which expose limited information of its observers.
This point is something like for each subscriber of a course , you need to get all of the subscribers from the course object so you can create a method in Course object which will give you the limited information for each subscriber of the course.

Retrieving data from WCF service

Let's say I have database with two tables - Groups and Items.
Table Groups has only two columns: Id and Name.
Table Items has three columns: Id, GroupId and Name.
As you can see, there is one-to-many relation between Groups and Items.
I'm trying to build a web service using WCF and LINQ. I've added new LINQ to SQL classes file, and I've imported these two tables. Visual Studio has automatically generated proper classes for me.
After that, I've create simple client for the service, just to check if everything is working. After I call GetAllGroups() method, I get all groups from Groups table. But their property Items is always null.
So my question is - is there a way to force WCF to return whole class (whole Group class and all Items that belong to it)? Or is this the way it should behave?
EDIT: This is function inside WCF Service that returns all Groups:
public List<Group> GetAllGroups()
{
List<Group> groups = (from r in db.Groups select r).ToList();
return groups;
}
I've checked while debugging and every Group object inside GetAllGroups() function has it's items, but after client receives them - every Items property is set to null.
Most likely, you're experiencing the default "lazy-loading" behavior of Linq-to-SQL. When you debug and look at the .Items collection - that causes the items to be loaded. This doesn't happen however when your service code runs normally.
You can however enforce "eager-loading" of those items - try something like this:
(see Using DataLoadOptions to Control Deferred Loading or LINQ to SQL, Lazy Loading and Prefetching for more details)
public List<Group> GetAllGroups()
{
// this line should really be where you *instantiate* your "db" context!
db.DeferredLoadingEnabled = false;
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Group>(g => g.Items);
db.LoadOptions = dlo;
List<Group> groups = (from r in db.Groups select r).ToList();
return groups;
}
Do you get the Items collection populated now, when you call your service?

silverlight 4 ria wcf- return multiple lists of complex objects

I need some help figuring out the right pattern for this situation:
I have a view with 5 cascading comboboxes. When you select a value from the first combobox, a service call is made to get the results for the next combobox, which is then enabled. The user makes the next selection and the process continues. This works fine. Next I'm given the case where the user returns to this view with the data already selcted, and the appropriate data already filled in each combobox.
I don't want to make all the calls over one by one to get the data, this seems wastefull. Instead I'd like to make one call and return all the data at once. Using RIA WCF Services, what is the best way to achieve this?
Here is what I've tried, but its not working as I hoped.
A) I made a class on the server side, then added a method to the service returning this type
public partial class SelectionValues
{
public List<Series> SeriesList {get;set;}
public List<BaseModel> BaseModelList {get;set;}
public List<FullModel> FullModelList {get;set;}
public List<Program> ProgramList {get;set;}
public List<ExtendedWarranty> ExtendedWarrantyList{get;set;}
}
[in the service]
/// <summary>
/// This function does nothing, just exposes the SelectionValues type
/// </summary>
/// <returns></returns>
public IQueryable<SelectionValues> getUnitSelectionValues()
{
throw new NotImplementedException();
}
Result: None of the lists generated on the client side.
B) So I added .Shared.cs to the class file, so the class would be the same on the client side. Then I wrote the Service method to return the data I need. The code works, but the data in the lists in the SelectionValues object don't come across to the client side.
[Invoke]
public SelectionValues GetValuesForExistingUnit( ..... )
{
SelectionValues result = new SelectionValues ();
...
return result
}
Is there a way to return multiple lists of complex objects at once, or am I doomed to make multiple calls chained together?
For what I know RIA Services only return Entities from your DomainService. I have done something similar where I needed to return a struct of my own. I solved that scenario by creating a simple WCF service that returns my new object with every list I want inside of it.
Keep in mind those objects are not in your Entityset so don't try to modify them and send them back to the server via a RIA Service.

objectcontext vs datacontext

i'm just new in developping silverlight, and i created a linq to sql connection and a service domain class. I want to get data from 2 tables which have a 1 to many relation into a datagridview. To do this i need to state include commands in my metadata and service domain class , but to do this i need to have an objectcontext instead of a datacontext(that i'm currently having ) can someone help me with this matter so i can use the include statement to get querys for my detail-grid
edit:
I've done what u said added the
"<IncludeAttribute()> _"
Public Property SubgroepIndustries As EntitySet(Of SubgroepIndustrie)
but i get this error message:
Error 1 'Include' is not a member of 'System.Data.Linq.Table(Of ILA4.HoofdgroepIndustrie')
edit 2:
when i try to use the include in my domain service class not the metadata so
Return Me.DataContext.HoofdgroepIndustries.Include("SubgroepIndustries")
doesnt work
ObjectContext is a class that is generated inside the generated DomainService class that you made.
Just do a this.ObjectContext in the DomainService class you made and you should have access to the class you are looking for.
I have assumed here that you are using RIA services and your DomainService MetaData class is tagged with [Include] attributes. Otherwise doing this.ObjectContext.SomeEntity.Include("ChildEntity") will not work out.
Edit:
Add <IncludeAttribute()> _ to Public Property SubgroepIndustries As EntitySet(Of SubgroepIndustrie) in your .metadata.vb
As for ObjectContext, looking at your code you don't need ObjectContext I think. Use DataContext instead.
so for example:
Public Function GetHoofdgroepIndustries() As IQueryable(Of HoofdgroepIndustrie)
Return Me.DataContext.HoofdgroepIndustries.Include("SubgroepIndustries")
End Function
is how you will do it.
Edit 2: You need Imports System.ServiceModel.DomainServices.Server for <IncludeAttribute()>

Stored Proc in RIA Services

I want to load some data with a SP.
I've put a SP in a Linq to SQL Class and I don't know how to use it for loading it's data in a datagrid.
In LinqToSqlDomainService I can't figure out how to call a SP.
What steps should I use.
Any samples of this ? All samples use a table.
Thank's
This post should hopefully be of help:
http://blogs.msdn.com/brada/archive/2009/08/24/business-apps-example-for-silverlight-3-rtm-and-net-ria-services-july-update-part-24-stored-procedures.aspx
You can create empty view with the same structure of your sproc and map that stored procedure to your function in your DomainService
See sample on http://cid-289eaf995528b9fd.skydrive.live.com/self.aspx/Public/sproc.zip
I found the following excellent step-by-step guide at this site -
http://betaforums.silverlight.net/forums/p/218383/521023.aspx
1) Add a ADO Entity Data Model to your Web project; Select generate from database option; Select your Database instance to connect to.
2) Choose your DB object to import to the Model. You can expand Table node to select any table you want to import to the Model. Expand Stored Procedure node to select your Stored Precedure as well. Click Finish to finish the import.
3) Right click the DB model designer to select Add/Function Import. Give the function a name (same name as your SP would be fine) and select the Stored Procedure you want to map. If your SP returns only one field, you can map the return result to a collection of scalars. If your SP returns more than one field, you could either map the return result to a collection or Entity (if all the field are from a single table) or a collection of Complex types.
If you want to use Complex type, you can click Get Column button to get all the columns for your SP. Then click Create new Complex type button to create this Complex type.
4) Add a Domain Service class to the Web project. Select the DataModel you just created as the DataContext of this Service. Select all the entitis you want expose to the client. The service functions should be generated for those entities.
5) You may not see the Complex type in the Entity list. You have to manully add a query function for your SP in your Service:
Say your SP is called SP1, the Complex type you generated is called SP1_Result.
Add the following code in your Domain Service class:
public IQueryable<SP1_Result> SP1()
{
return this.ObjectContext.SP1().AsQueryable();
}
Now you can compile your project. You might get an error like this: "SP1_Result does not have a Key" (if you not on RIA service SP1 beta). If you do, you need to do the following in the service metadata file:
Added a SP1_Result metadata class and tagged the Key field:
[MetadataTypeAttribute(typeof(SP1_Result.SP1_ResultMetadata))]
public partial class SP1_Result
{
internal sealed class SP1_ResultMetadata
{
[Key]
public int MyId; // Change MyId to the ID field of your SP_Result
}
}
6) Compile your solution. Now you have SP1_Result exposed to the client. Check the generated file, you should see SP1_Result is generated as an Entity class. Now you can access DomainContext.SP1Query and DomainContext.SP1_Results in your Silverlight code. You can treat it as you do with any other Entity(the entity mapped to a table) class.
Calling a stored procedure is trivial. Import it as a function and then invoke the function as a member of the DDS. The return value is an ObservableCollection<> that you can use to set up the DataContext of the object you want to bind.
...unless you want to use it in a Silverlight RIA app via the magic code generated proxy, in which case your goose is cooked unless your result rows exactly match one of the entities. If you can meet that criterion, edit the DomainService class and surface a method that wraps the ObjectContext method.