locked
EF 4 question - model different from database schema RRS feed

  • Question

  • I'm new to EF 4. One of the things that appealed to me when I started learning EF was the statement "In the Entity Framework , you can define the conceptual model, storage model, and the mapping between the two in the way that best suits your application." You will see this statement repeated over and over again in anything written about EF.

    The problem is that it doesn't seem to be true.

    I started with a "toy" database (Brian Noyes' TaskManager database from the WCF RIA Services walkthrough). This db has a TimeEntry table with non-nullable datetime columns. Now, when the user adds a time entry, I don't want to provide default values for these columns; I want them to be null and force the user to enter values. Then, when the user tries to commit the new record, they should get a validation error if the required fields aren't filled in. Simple, solution, I thought: Make them nullable in the conceptual model.

    Wrong. Then I get: Error 3031: Problem in mapping fragments starting at line 336: Non-nullable column TimeEntry.StartTime in table TimeEntry is mapped to a nullable entity property.

    So the most trivial difference between the conceptual model and storage model is not supported? This is a showstopper. Our in-memory model (that the user directly edits) is ALWAYS different from our storage model, because the essence of editing is working with partially invalid data until you're done and ready to save. At that point, you have to resolve validation errors. (IOW, the path from one valid state to another may take you through one or more invalid states, and that's just fine.)

    Oh, and I can't remove columns from my conceptual model either (if they are non-nullable in the database). What if that entity in my c-model is read-only, and I don't care about inserts and updates?

    I must be missing something. I hope you EF experts out there can clear this up, because I can't see how to make my conceptual model "suit my application" if it's in this kind of a straitjacket.

    Sunday, November 14, 2010 5:39 PM

Answers

  • Let's leave the question of how validation is actually implemented aside for a moment, and just talk about the model: What I'm hearing is that you created a second model (using DTOs) and mapped this model to the EF model. How did you create this second model? By hand, or using some kind of tool? How do you map the two models, so that (for example) creating a new object instance in one model causes an equivalent instance to be created in the other?

    At first blush, this sounds like just moving the problem around. I've got a model (implicitly) in my database, and I've used the EF designer to map that to another model. Now I need to create a third model and map that to my EF model? What would I use to create that third model and map it to the EF model? What benefit is the EF model giving me in this scenario?

    When I read the WCF RIA Services material, the main benefit Microsoft seems to be selling is to bring my EF entities all the way to the client and data-bind them directly to my Silverlight UI. If I can't solve real-world problems with this stack, what's the point of all this stuff? I still feel like I'm missing something...

    Hello,

    Since you mentioned WCF service, most probably you work with POCO objects, right? POCO means Plain Old CLR Objects. To use poco entities, you need a model without generating code. Hence, you need to manually create your own entities or use an entity Generator to do that automatically. The scenario to use POCO is we already have those entities what we need is to map those entities to the model in order to manipulate data in database. For more information, please read:
    http://msdn.microsoft.com/en-us/library/dd456853.aspx

    There is a series article introducing POCO entities in ado.net team blog, I hope it could help you:
    POCO in Entity Framework: Part 1
    POCO in Entity Framework: Part 2
    POCO in Entity Framework: Part 3

     


    Best Regards,
    Roahn Luo
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com
    Thursday, November 25, 2010 7:41 AM

All replies

  • On 11/14/2010 11:39 AM, RScullard wrote:
    > I'm new to EF 4. One of the things that appealed to me when I started
    > learning EF was the statement "In the Entity Framework , you can define
    > the conceptual model, storage model, and the mapping between the two in
    > the way that best suits your application." You will see this statement
    > repeated over and over again in anything written about EF.
    >
    > The problem is that it doesn't seem to be true.
    >
    > I started with a "toy" database (Brian Noyes' TaskManager database from
    > the WCF RIA Services walkthrough). This db has a TimeEntry table with
    > non-nullable datetime columns. Now, when the user adds a time entry, I
    > don't want to provide default values for these columns; I want them to
    > be null and force the user to enter values. Then, when the user tries to
    > commit the new record, they should get a validation error if the
    > required fields aren't filled in. Simple, solution, I thought: Make them
    > nullable in the conceptual model.
    >
    > Wrong. Then I get: Error 3031: Problem in mapping fragments starting at
    > line 336: Non-nullable column TimeEntry.StartTime in table TimeEntry is
    > mapped to a nullable entity property.
    >
    > So the most trivial difference between the conceptual model and storage
    > model is not supported? This is a showstopper. Our in-memory model (that
    > the user directly edits) is ALWAYS different from our storage model,
    > because the essence of editing is working with partially invalid data
    > until you're done and ready to save. At that point, you have to resolve
    > validation errors. (IOW, the path from one valid state to another may
    > take you through one or more invalid states, and that's just fine.)
    >
    > Oh, and I can't remove columns from my conceptual model either (if they
    > are non-nullable in the database). What if that entity in my c-model is
    > read-only, and I don't care about inserts and updates?
    >
    > I must be missing something. I hope you EF experts out there can clear
    > this up, because I can't see how to make my conceptual model "suit my
    > application" if it's in this kind of a straitjacket.
    >
     
    Most developers don't validate an object in the manner in which you
    speak. The object is validated to be valid well before it's persisted to
    a database. It's not up to the model to determine if your object is
    valid. If a property in the object is not suppose to be null or
    string.empty, then you had better validate the object to not have those
    property values to persist it.
     
    Maybe, you need to inject the object in to a Windows Workflow that has
    activities that validate the object, every property in the object must
    be valid and an child object's properties within the parent object must
    be valid in order to persist it or them.
     
    I used DTO(s) and mapped data between a DTO and Entity. The user never
    edited a EF entity directly. The DTO for the parent had DTO child
    objects that were mapped back to entities, along with the parent.
     
    The DTO and all child objects, and there were several object graphs with
    in the parent, were sent through a Windows Workflow that sat behind the
    WCF service. The user pushed the save button and sent the object.
     
    Windows Workflow validated the DTO, and if all aspects of the DTO and
    its child DTO(s) were not valid, the DTO was kicked back, which had an
    error collection of errors that were displayed to the user. The user
    made the corrections to the DTO using edits on the DTO, and the user
    sent the DTO again. The DTO is either valid at that point to persist the
    DTO or DTO(s) in it or it's not valid and kick it back.
     
    The DTO(s) are an abstraction layer above the model, and the user works
    with the DTO(s).
     
     
     
    • Marked as answer by liurong luo Monday, November 22, 2010 1:54 AM
    • Unmarked as answer by RScullard Monday, November 22, 2010 2:23 PM
    Sunday, November 14, 2010 7:16 PM
  • Let's leave the question of how validation is actually implemented aside for a moment, and just talk about the model: What I'm hearing is that you created a second model (using DTOs) and mapped this model to the EF model. How did you create this second model? By hand, or using some kind of tool? How do you map the two models, so that (for example) creating a new object instance in one model causes an equivalent instance to be created in the other?

    At first blush, this sounds like just moving the problem around. I've got a model (implicitly) in my database, and I've used the EF designer to map that to another model. Now I need to create a third model and map that to my EF model? What would I use to create that third model and map it to the EF model? What benefit is the EF model giving me in this scenario?

    When I read the WCF RIA Services material, the main benefit Microsoft seems to be selling is to bring my EF entities all the way to the client and data-bind them directly to my Silverlight UI. If I can't solve real-world problems with this stack, what's the point of all this stuff? I still feel like I'm missing something...

    Monday, November 15, 2010 3:16 PM
  • Sorry to re-ask, but I'm really trying to figure this out, and if anyone could point me to an article or sample that addresses these questions, I would greatly appreciate it! (I'm working my way through the new Lerman book, but so far it doesn't answer these questions.)
    Tuesday, November 16, 2010 10:57 PM
  • Let's leave the question of how validation is actually implemented aside for a moment, and just talk about the model: What I'm hearing is that you created a second model (using DTOs) and mapped this model to the EF model. How did you create this second model? By hand, or using some kind of tool? How do you map the two models, so that (for example) creating a new object instance in one model causes an equivalent instance to be created in the other?

    At first blush, this sounds like just moving the problem around. I've got a model (implicitly) in my database, and I've used the EF designer to map that to another model. Now I need to create a third model and map that to my EF model? What would I use to create that third model and map it to the EF model? What benefit is the EF model giving me in this scenario?

    When I read the WCF RIA Services material, the main benefit Microsoft seems to be selling is to bring my EF entities all the way to the client and data-bind them directly to my Silverlight UI. If I can't solve real-world problems with this stack, what's the point of all this stuff? I still feel like I'm missing something...

    Hello,

    Since you mentioned WCF service, most probably you work with POCO objects, right? POCO means Plain Old CLR Objects. To use poco entities, you need a model without generating code. Hence, you need to manually create your own entities or use an entity Generator to do that automatically. The scenario to use POCO is we already have those entities what we need is to map those entities to the model in order to manipulate data in database. For more information, please read:
    http://msdn.microsoft.com/en-us/library/dd456853.aspx

    There is a series article introducing POCO entities in ado.net team blog, I hope it could help you:
    POCO in Entity Framework: Part 1
    POCO in Entity Framework: Part 2
    POCO in Entity Framework: Part 3

     


    Best Regards,
    Roahn Luo
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com
    Thursday, November 25, 2010 7:41 AM