Entity Framework, Code First and relational data


  • BINNED

    I'm jumping into asp.net mvc with entity framework, and having some problems with getting create/edit actions to take.

    I have two models, one of which contains a reference to the other:

    public class Model1
    {
        public int Id {get; set; }
        public string  Name {get; set; }
        // various other properties
    }
    
    public class Model2
    {
        public int Id {get; set; }
        public Model1 model {get; set; }
        // and some other stuff
    }
    

    Model1 is seeded to have some static data, no controller or views for viewing or editing it. Model2 has a scaffolded controller and views with the standard CRUD actions. On create and edit, everything seems to go into the database OK, and the Model1_id column is populated correctly, but back on the index page, when the controller gets the db.Model1s.ToList() to populate the list, every Model2 I've created has a null Model1 field, and the column in the view is empty.

    This seems like such a standard thing to do that I'm almost certainly missing a simple, obvious part of the puzzle, but I'm failing to find the right Google terms to get anything that looks like my problem.



  • @Jaloopa Things may have improved, but years ago when I tested this code first thing with was full of errors like a field not saving with no error message. I put this thing on the shit list and never looked again.


  • sockdevs

    @Jaloopa EF uses lazy-loading, so it'll only load Model1 into Model2 when it's required, so long as you use the original collection returned by EF. Given you're ToList()ing (and making a new collection as a result), by the time you access the Model1 property, you've left the DB context, and the lazy loading doesn't kick in.

    I hope that makes sense.


  • BINNED

    @RaceProUK said in Entity Framework, Code First and relational data:

    Given you're ToList()ing

    That's what the scaffolding added. Is there a better way?

    @RaceProUK said in Entity Framework, Code First and relational data:

    it'll only load Model1 into Model2 when it's required

    Surely it's required when it tries to show the Model1 column in the list of Model2s? What do I need to do to get it to load at this point?


  • sockdevs

    @Jaloopa said in Entity Framework, Code First and relational data:

    That's what the scaffolding added. Is there a better way?

    Yes: use the collection returned by EF i.e. don't call ToList().

    @Jaloopa said in Entity Framework, Code First and relational data:

    What do I need to do to get it to load at this point?

    So long as you're using the collection originally returned by EF (and you've not disposed the context), it'll be automatic.



  • @RaceProUK said in Entity Framework, Code First and relational data:

    Yes: use the collection returned by EF i.e. don't call ToList().

    Or use Include("model") (I think you pass a property name?)


  • sockdevs

    @Maciejasjmj Either that, or a lambda that resolves to the correct property, I forget which.


  • BINNED

    @RaceProUK OK, I've changed the GET Index() method in the controller from return View(db.Model1s.ToList()) to return View(db.Model1s), and I'm still getting the same result. db, the DbContext derived class I have, is a field so shouldn't be disposed until the controller is.

    @Maciejasjmj said in Entity Framework, Code First and relational data:

    Or use Include("model")

    The Create() and Edit() POST methods have that in the signature: public ActionResult Edit([Bind(Include = "Id,model,Name")] Model2 model2). Should that be somewhere else as well?



  • @Jaloopa said in Entity Framework, Code First and relational data:

    The Create() and Edit() POST methods have that in the signature: public ActionResult Edit([Bind(Include = "Id,model,Name")] Model2 model2). Should that be somewhere else as well?

    Oh, no, that's for something else.

    You'd include your Include when performing the query, so it would be something like db.Model2s.Include("model").ToList() to give you a List<T> of Model2s which have the model property filled.


  • BINNED

    @Maciejasjmj Awesome, that's worked (apart from stringifying the whole thing, but I'm sure I can work out what attribute I need to just show the name).

    This hasn't come up in any of the tutorials I've gone through. What should I have been searching for?



  • @Jaloopa said in Entity Framework, Code First and relational data:

    What should I have been searching for?

    Cookies. Then you bring them to me.



  • F*ck Entity Framework with a big purple cactus and teach yourself some proper database querying instead. Databases deserve some love and attention, they're way too powerful to be treated like some black box in which you cram some data by magic. :slight_smile:


  • BINNED

    @AlexMedia said in Entity Framework, Code First and relational data:

    teach yourself some proper database querying instead

    I'm perfectly capable of handling the database side of things myself, but MVC encourages you to use EF and it supposedly makes things simple compared to doing all the SqlConnection boilerplate yourself. Of course, it's a leaky abstraction and the minute you go outside of what's explicitly supported it starts to unravel


  • sockdevs

    @Jaloopa I find EF and similar are best if you're just doing simple table access and basic queries. If you're doing anything fancy, it's normally better to put that in a stored procedure. But that doesn't mean you can't still use EF and stuff, as they can also handle stored procedures (in LINQ to SQL, they become a method directly on the context class).



  • @Jaloopa said in Entity Framework, Code First and relational data:

    I'm perfectly capable of handling the database side of things myself,

    Good to hear that there still are people who know what's going on under the hood. These days I see it way too often that people see a database as something that a DbContext talks to and nothing more.

    but MVC encourages you to use EF

    Of course, because it's supplied by Microsoft. Before EF came along, those same people recommend Linq2SQL and before that they recommended whatever was the data access fad of the time.

    and it supposedly makes things simple compared to doing all the SqlConnection boilerplate yourself. Of course, it's a leaky abstraction and the minute you go outside of what's explicitly supported it starts to unravel

    I totally agree. It happens way too often that a tool like EF restricts you in what you want to do, because of its own limitations.

    There are few people who like the boilerplate of DataReaders and SqlConnections. Mapping code is boring to write and tedious to change whenever you add or update a field.

    That's why I am interested in microORMs such as Petapoco or Dapper. They spare you the boring work but still give you the freedom to write your own SQL queries and tables, unlike "frameworks" such as EF which force their way of working upon you.



  • @AlexMedia said in Entity Framework, Code First and relational data:

    F*ck Entity Framework with a big purple cactus and teach yourself some proper database querying instead. Databases deserve some love and attention, they're way too powerful to be treated like some black box in which you cram some data by magic. :slight_smile:

    You can pry Hibernate from my cold, dead hands. SQL, too. They're both the right tool for their respective jobs.



  • @AlexMedia said in Entity Framework, Code First and relational data:

    They spare you the boring work but still give you the freedom to write your own SQL queries and tables, unlike "frameworks" such as EF which force their way of working upon you.

    EF lets you execute a stored procedure if you need to, and if you don't keep your SQL bits in sprocs but pepper them in strings throughout your codebase then you're :doing_it_wrong:.

    It also lets you code the table up with indices, hints and whatever you need and hook the EF model to that. If you need it. And it also lets you comfortably whip your table up code-first if you don't. So that's more choice, not less.



  • @Jaloopa said in Entity Framework, Code First and relational data:

    but MVC encourages you to use EF

    EF with database-first is fine, but code-first was a half assed thing to satisfy the DDDers.



  • @fbmac said in Entity Framework, Code First and relational data:

    code-first was a half assed thing to satisfy the DDDers.

    Data Definition Disaster?



  • @fbmac said in Entity Framework, Code First and relational data:

    @Jaloopa said in Entity Framework, Code First and relational data:

    but MVC encourages you to use EF

    EF with database-first is fine, but code-first was a half assed thing to satisfy the DDDers.

    Double Dumb Douchebags ?




Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.