Question

I am currently stuck in the design of this solution.

The data layer design consists of the following:

  • Recipe (parent high level object)
    • Language Detail (name, description by language) (many)
      • Headers (many)
      • Steps (many)
        • Ingredients (many)
        • Quantities (many)
        • Procedures (many)
      • Notes (many)

The challenge that I am having is how to create a data access design that will add/remove the child objects in the database when the object is populated from a WCF SaveRecipe(recipe) method?

This all stems from the management asking us to add a communications layer in our application, right now our UI is coupled to our business layer, and the BL is directly coupled to the DAL, we basically need the injection of WCF between the BL and DAL.

I have read in this thread that using L2S isn't a good idea over WCF, but since the design isn't new, we have to use this type of methodology, and then move away from it once we can refactor the heavy amounts of UI work.

Was it helpful?

Solution

If you are trying to send stuff down the line with WCF I suggest you create a model of the data you want to move around your domain. As far as I've found you can't serialize IQueryable objects, but you can create a set of classes that Linq populates and then serialize that. For example:

[DataContract]
public class Recipe {

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Description { get; set; }

    [DataMember]
    public List<Ingredient> Ingredients { get; set; }

}

Then fill that up with

List<Recipe> recipes = (from r in dc.recipe
                           select new Recpie {
                               Name = r.name,
                               Description = r.description,
                               Ingredients = (Linq code to make list of ingredients)
                           }).ToList();

And then sending the list down the line with WCF becomes a piece of cake.

OTHER TIPS

I like this answer from Karl on the thread you referenced:

It is better to create your own classes for the transfer of data object. Those classes, of course, would be implemented as DataContracts. In your service layer, you'd convert between the linq-to-sql objects and instances of the data carrier objects. It is tedious but it decouples the clients of the service from the database schema. It also has the advantage of giving you better control of the data that is passed around in your system.

It looks like you're going to have to refactor anyways - just as well start by refactoring out the dependency to linq2sql in your UI layer.

I don't think you have a quick and easy solution.

I don't recommend exposing L2S classes over WCF. Create a hierarchy of DataContract objects, and pass those over WCF. The downside of this is that you have to "deep copy" your L2S objects into your DataContract hierarchy, but the upside is that you can only include fields that are necessary and proper for transport over a network. For example, in a project I'm working on now, I pass an EmployeeData object over the network that includes most of my L2S Employee fields but excludes things like the employee's salted hash & password salt.

It could also be an idea to create classes both including and excluding child entries. I have sometimes created classes like this:

class Recipe {
    [DataMember] public string Name;
    [DataMember] public string Description;
}

class RecipeWithIngredients : Recipe {
    [DataMember] public IList<Ingredient> Ingredients;
}

Edit: inadvertedly posted before the post was finished.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top