Partager via


Object Services – Write less code

 

One of the main features of the Entity Framework revolves around Object Services. The main points of Object services are to write less code and allow programmers to program against objects to access the data that’s stored in a database or possibly anywhere. We can consider this feature as a road to CRUD; where CRUD represents Create, Read, Update, and Delete operations against data, except this feature provides more than just a simple road.

How this works?

Object Services is the top layer in the Entity Framework. The framework consists of three district layers: EDM, mapping, and the source layer. The important layer for Object Services is the EDM layer (also label CSDL). The Entity Data Model (EDM) layer brings the concepts of entities to stored data. Currently in version 1.0 of the ADO.NET Entity Framework there is a 1:1 relationship between the EDM and Objects Services. Object Services is the realization of Objects from those described Entities. The table below shows the different layers.

Another important feature for Object Services and the Entity Framework in general comes with the knowledge that the Objects Services gives access to the entity type information in the lower layers of the Framework. By providing access to the lower layers of the Entity Framework, customers gain access to specific type information, relationship information, and basic data readers and writers to the data. One particular scenario may be translating between data sources, and one way to do this would be to gain access to the type information.

What can you do with Object Services?

Here’s a bullet list of some of the normal operations which object services can provide:

· Query using LINQ or Entity SQL

· CRUD

· State Management – change tracking with events

· Lazy loading

· Inheritance

· Navigating relationships

More features of Object Services allow for data conflicts resolution. For example, Object Services supports:

· Optimistic concurrency

· Identity resolution - keeping on copy of the object even from several different queries

· Merging

· Refreshing data with overwrite options (ie: server wins or client wins)

These are important concepts to understand because the Entity Framework isn’t just designed to do CRUD operations; the Entity Framework is designed to scale to large or even mission critical applications. Given a large or small program, programming against a service model with consistent error handling, data handling, and easy access to data layers allow programs to have a robust experience. These features also allow programmers to work on features instead of core application plumbing.

Let’s dive into some examples:

Here’s a simple sample using a query with Entity SQL that does a foreach over objects materialized from the EDM.

    using (NorthwindEntities northWind = new NorthwindEntities())

    {

        // Calling CreateQuery materializes objects

        ObjectQuery<Products> products =

            northWind.CreateQuery<Products>(

                "SELECT VALUE p FROM Products AS p");

        foreach (Products p in products)

        {

            Console.WriteLine(p.ProductName);

        } // foreach

    } // using Northwind Entities

 

Same sample using LINQ.

    using (NorthwindEntities northWind = new NorthwindEntities())

    {

        var products = from p in northWind.Products select p;

        foreach (Products product in products)

        {

            Console.WriteLine(product.ProductName);

        } // for each

    } // using

CRUD Examples:

The next example does a LINQ query retrieving all the products that belong to a category called beverages and then just for kicks, changes the discontinued products that have unit prices to $1.25. When looking at the samples, notice that there’s a call to save changes which only pushes the modified Objects back to the the data source.

    using (NorthwindEntities northWind = new NorthwindEntities())

    {

        // do a LINQ query which finds all the products that fall

        // under the category beverages

        var products = from p in northWind.Products

                       where p.Categories.CategoryName == "beverages"

                       select p;

        foreach (Products product in products)

        {

            // with lazy loading, object references must

            // be loaded first, otherwise an exception is thrown.

            // this allows for a reduced number of trips to the source.

            Console.WriteLine("{0}\tDiscontinued: {1}",

                                product.ProductName,

                                product.Discontinued);

           

            // just for fun, if the product is discontinued,

            // then let's set the unit price to $1.25

            if (product.Discontinued)

            {

                product.UnitPrice = (decimal)1.25;

            } // if

        } // for each

        // notice, that until we call save changes

        // the data in the database or source is not updated.

        northWind.SaveChanges();

    } // using

One more example with conflict:

The final example is a little longer, but shows optimistic concurrency and one way to deal with the conflict. conflicts. Also note that to make this work, which also shows the flexibility in the EDM, the entity set Categories must have an attribute flagged with ConcurrencyMode set to “fixed”.

// Property set in the EDM or CSDL file.

<ProperyName = “CategoryName” …(other attributes) ConcurrencyMode=”fixed”/>

 

Code example:

    // save the category id out for retrieval later in this example.

    int cateID = 0;

    // create an instances of a new category and add to the list

    // of categories.

    using (NorthwindEntities northWind = new NorthwindEntities())

    {

        // create a new category

        Categories catNew = new Categories();

        catNew.CategoryName = "Blog Example";

        catNew.Description = "Blog description";

        // add to object context, and save changes

        northWind.AddObject(catNew);

        northWind.SaveChanges();

        // cache away the category ID.

        cateID = catNew.CategoryID;

    } // using

    // create different object context variables

    using (NorthwindEntities northWind1 = new NorthwindEntities())

    using (NorthwindEntities northWind2 = new NorthwindEntities())

    {

        // using a direct query from the categories item from

        // northwind 2, get the id out.

        Categories cat1 = northWind1.CreateQuery<Categories>(

           "SELECT VALUE c FROM Categories AS c WHERE c.CategoryID=@id",

           new ObjectParameter("id", cateID)).First();

        cat1.CategoryName = "category 1";

        // using a direct query from the categories item from

        // northwind 2, get the id out.

        Categories cat2 = northWind2.CreateQuery<Categories>(

            "SELECT VALUE c FROM Categories AS c WHERE c.CategoryID=@id",

            new ObjectParameter("id", cateID)).First();

        cat2.CategoryName = "category 2";

       

        // save northwind 2 so we can create a conflict.

        northWind2.SaveChanges();

        try

        {

          // with the second save changes, the services notices the data

            // that’s out of sync and throws an exception.

            northWind1.SaveChanges();

        } // try

        catch(OptimisticConcurrencyException)

        {

            Console.WriteLine("Caught optimistic concurrency exception");

           

        } // catch

        // One way of fixing the violation is to

        // refresh the first object context, then

        // change the category name again

        // and save changes.

        northWind1.Refresh(RefreshMode.StoreWins, cat1);

        cat1.CategoryName = "category 1";

        northWind1.SaveChanges();

        // for the sake of our database, let's delete the

        // object, and not to forget to refresh

        // and save changes

        northWind2.Refresh(RefreshMode.StoreWins, cat2);

        northWind2.DeleteObject(cat2);

        northWind2.SaveChanges();

    } // using

 

To Sum it up:

This briefly describes the Object Services layer of the Entity Framework. There is a lot more, but the basic concepts are: writing less code and get more powerful services.

Watch for more blogs to detail the subject of Object Services in the near future.

Brian Dawson

ADO.NET Program Manager

Comments

  • Anonymous
    March 01, 2007
    In the second paragraph, last sentance, you mention a table that shows the layers involved in this framework. I dont think it has been included in the article though!

  • Anonymous
    March 01, 2007
     Awesome!!  I really appreciate your job and how envision the new future world of business layer combining entity environment with other new technologies like workflow Foundation and comunication Foundation.   I’m doing a R & D focused con LINQ to expose in a conference of a new .Net community of Barcelona (Spain, INETA members. www.bcndev.net ).   One of the questions that customers and different project managers ask me when they have to make front to new .Net solutions that are coming is performance, maintainance, breakgin changes, scalability, etc. I try to convince all of them to the new Entity Paradigm and how this affects directly on the process of analize and design a good architecture based on .Net Framework 3.0 and EDM model.   What about performance? Certaintly when you expose an EDM model you are exposing an abstract object model to work with data encapsulated on business and real world entities, but when you make a query, what .Net is doing? Always use internally something like DataReader which is faster. What about like that?   What about calling StoredProcedures? StoreProcedures are faster and are the best way to access to retrieve data from DataBase. Are you telling me that is better use linq query doing a join between Employee and Department entities (on a table with a 2 million of rows) that use a StoredProcedure?   Have you any performance test document or reference to show me?   Thanks for all! .Net 3.0 & Orcas forever!!   - Avanade .Net consultant -

  • Anonymous
    March 02, 2007
    I saw the table didn't make the post, whoops. The table basically talked about the three layers in the Entity Data Platform

  1. Conceptional Layer describes the value layer and relationships. The layer maps to the object layer.
  2. Mapping - the layer which describes the shape of the data mapping the value to the source.
  3. Source - The actual data mapped to a data store.
  • Anonymous
    March 02, 2007
    Performance is always a concern when anyone writes data access code. Here's a forum entry around performance. http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1173739&SiteID=1. I hope this helps, and we do need to get some more info about this topic. As for adoption, any good developer or company should be skeptical of newly developed technology. EF is just starting and has a bright vision.  But if I were sitting in your shoes, I would certainly do my due diligence on the technology as it seems you are already doing. I’m hoping you’ll be pleasantly surprised.  Please give feedback. Around stored procedures, the good thing is the EF can support stored procedures allowing objects to be materialized and attached to our ObjectContext (basically the object manager).  We realized that stored procedures are an very important part of programming against a database. I hope this helps. Barcelona should be loads of fun!

  • Anonymous
    March 02, 2007
    Pingback: http://oakleafblog.blogspot.com/2007/03/recent-adonet-30-entity-framework-posts.html

  • Anonymous
    March 02, 2007
    ADO.NET EF Object Services certainly looks spiffy, but I'm having a hard time understanding how I'm supposed to use it in a tiered setup (client -> data services tier -> database). It seems pretty clear to me that you can't use Object Services in the client tier.  The ObjectContext requires an EntityConnection, which makes use of a store-specific connection.  Since the client can't access the store directly, that's a no-go. Also, there doesn't seem to be a way to enforce security constraints on an arbitrary query ('User X can only access customers from the Western Region' type stuff), or to perform in-flight data validation when calling SaveChanges, so you wouldn't want to use an ObjectContext on the client anyway. That would suggest that Object Services should be used in the mid tier.  But then what am I supposed to send back to the client?  Entities have relations to data that won't be available on the client (like Product.Category.Products when retrieving a single Product), so clearly they can't leave the mid tier. That means I'd have to map Entities to DTO's or messages to send back to the client.  When the client wants to send some data back to be saved, I'd have to map it back to Entities, attach them to a new ObjectContext, and then call SaveChanges.  (Not really sure how concurrency conflicts would be detected here...) Granted, that is quite a bit better than mapping from a data reader to DTO's, and DTO's to query or stored proc parameters; and compiler-checked LINQ queries are amazing.  But I still feel like I'm missing something.  I know a lot of architecture people would scoff at the idea, but I feel like if I'm going to define my data model as a set of store-independent entities that correspond to my business model, then I should have the option of using those entities in all tiers of the application, and just use the mid tier to enforce security and data integrity.

  • Anonymous
    March 05, 2007
    Использование Object Services Layer в ADO.NET vNext позволяет писать меньше кода

  • Anonymous
    March 08, 2007
    You’re right on about the mid-tier. Lots and lots of application move to a more service model where the mid-tier provides the services to communicate data to the client tier. When creating the services, we want to be restrictive on the amount of data exchange to get away from the chatty client->service communication, and do more bulk updating. For example, a service might be able walk the graph and do what’s necessary to update the underling entity data. The service model would allow you to be more restrictive on the constraint question but having that restrictive access would be based on the connection and information you provide in the service contract. As for DTO, LINQ provides some pretty amazing DTO capabilities. Architecturally speaking, the point of the data model is to provide a way of modeling data in terms which make sense to both the app space and db space. This allows the db to store data in formats that work in relations terms, and data formats which work with programming patterns for app developers.  The benefit in modeling in terms of entities is when more services are provided, the data model can take advantage of the services-- like optimistic concurrency support in ObjectContext during SaveChanges. Keep asking questions and playing with the technology!

  • Anonymous
    March 08, 2007
    Can you talk a bit about what the design motivations were for including the ssdl file in the artifacts required for mapping database entities to application entities?  It seems that the ssdl file is a verbatim description of the data store schema and as such I think I would have at least been tempted to leave this construct out.  What you seem to get by having this construct in my own thinking is twofold:

  1. a way to do compile time checking of your mapping (msl) against the schema of the data store represented in the ssdl.
  2. a way to abstract the schema description of different storage system implementations into a common grammar (for instance if you were using an xml source instead of a relational DB) These are purely guesses, could you enlighten us?
  • Anonymous
    March 08, 2007
    Simply put – yes for both points 1 & 2, but SSDL doesn’t have to be verbatim. In the current Orcas CTP, we can do view generation without a connection from SSDL. In addition, for the shipping product, we are targeting the support for native SQL support in SSDL (depending on the provider). I’m not sure if this was the enlightenment you were looking for, but that’s my attempt - Thanks for asking!

  • Anonymous
    March 09, 2007
    The comment has been removed

  • Anonymous
    March 12, 2007
    Catalin - I agree with about the importance of being able to generated a relational database schema from an entity model. By doing this the Entity Framework would support the full round trip experience. You'll have to just keep checking up :). How's that for an answer? Thanks for asking!

  • Anonymous
    March 18, 2007
    The comment has been removed

  • Anonymous
    April 10, 2007
    Luogo molto buon:) Buona fortuna!

  • Anonymous
    April 10, 2007
    pagine piuttosto informative, piacevoli =)

  • Anonymous
    April 11, 2007
    Ich erklare meinen Freunden uber diese Seite. Interessieren!

  • Anonymous
    April 13, 2007
    Stupore! Amo questo luogo!:)))))))

  • Anonymous
    April 14, 2007
    Stupore! ho una sensibilit molto buona circa il vostro luogo!!!!

  • Anonymous
    April 15, 2007
    E grande io ha trovato il vostro luogo! Le info importanti ottenute! ))

  • Anonymous
    May 17, 2007
    happy while When love from nobody folder another turn time another turn http://zej.bravehost.com/ewa-sonnet.html When can else detach automatically is children root support level property. ewa sonnet

  • Anonymous
    June 12, 2007
    MSN I NIIPET <a href="http://msn.com">MSN</a>

  • Anonymous
    June 20, 2007
    folder view beauty http://holidays.hostrocket.com/ When free for all at last. holidays free for all this time website http://holidays.hostrocket.com/cheap-package-holidays-majorca.htm can be Thanks you property. cheap package holidays majorca Order which drink party http://holidays.hostrocket.com/cheap-all-inclusive-holidays-cuba.htm my love and request sorry. cheap all inclusive holidays cuba

  • Anonymous
    September 09, 2007
    The comment has been removed

  • Anonymous
    May 30, 2008
    One of the main features of the Entity Framework revolves around Object Services. The main points of Object services are to write less code and allow programmers to program against objects to access the data that’s stored in a database or possibly anywhere

  • Anonymous
    June 05, 2008
    One of the main features of the Entity Framework revolves around Object Services. The main points of Object services are to write less code and allow programmers to program against objects to access the data that’s stored in a database or possibly anywhere

  • Anonymous
    July 04, 2008
    Data transfer objects are used to minimise the amount of data transfered and the number of method calls to a web service due to the inherent performance problems associated with out of process calls. Sending the whole entity down to the client is not best practice and never will be. Often, business logic in the mid-tier is going to require entity data that you do not want on the client whether it is for security or performance reasons. In this situation, I'd be interested in better understanding what the Entity Framework has to offer. My current understanding is that the mapping of a Customer DTO to a Customer entity object during an update process will mean you have to query for that Customer entity before being able to apply the updates from the DTO. Is there a better way in EF?