3

I've been at this same question in different forms now for a while (see e.g. Entity Framework and MVC 3: The relationship could not be changed because one or more of the foreign-key properties is non-nullable ), and it's still bugging me, so I thought I'd put it a little more generically:

I feel this can't be a very unusual problem:

You have an entity object (using Entity Framework), say User. The User has some simple properties such as FirstName, LastName, etc. But it also has some object property lists, take the proverbial example Emails, to make this simple. Email is often designed as a list of objects so that you can add to that object properties like Address and Type (Home, Work, etc). I'm using this as an example to keep it generic, but it could be anything, the point is, you want the user to be able to add an arbitrary number of these items. You should also be able to delete items (old address, or whatever).

Now, in a normal web page you would expect to be able to add these items in the same View. But MVC as it seems designed only makes it easy to do this if you call up an entirely new View just to add the address. (In the template for an Index View you get the "Create New" link e.g.).

I've come across a couple of examples that do something close to what I mean here:

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

and

http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/

The problem is, although the sample projects on these sites work fine, with mock model objects, and simply lists (not an object with a child list), it's a different thing if you actually want to do something with the posted information - in my case save to database through the Entity Framework model. To adapt these cases to that, all of a sudden I'm in a maze of intricate and definitely not DRY code... Juggling objects with AutoMapper and whatnot, and the Entity Framework won't let you save and so on (see above link if you're interested in the details).

What I want to get at is, is it really possible that this is such an uncommon thing to want to do? Update a child collection in the same View as the parent object (such as the email addresses in this case)? It seems to me it can't be uncommon at all, and there must be a standard way of handling this sort of scenario, and I'm just missing it (and no one here so far has been able to point me to a straighforward solution, perhaps because I made it too abstract with my own application examples).

So if there is a simple solution to what should in my view be a simple problem (since the design is so common), please tell me.

Community
  • 1
  • 1
Anders
  • 12,556
  • 24
  • 104
  • 151

1 Answers1

0

Have you tried updating the project at your link to Steven Anderson's blog to bind to a complex object? Create a class in models called Sack and give it a single property and see if you can get it to work.

public class Sack
{
    public IEnumberable<Gift> Gifts { get; set; } 
}

It only took me a minute to get it up and running as I think you intend. The improvement I would have made next would be to add an HtmlHelper extension that is essentially the same as Html.EditorFor(m => m.SomeProperty), only call it something more meaningful and have it interface with the prefix scope extensions provided in the project.

public static class HtmlExtensions
{
    public static IHtmlString CollectionEditorFor<TModel, TValue>(this HtmlHelper html, Expression<Func<TModel, TValue>> expression)
    {
        if (/* type of expression value is not a collection */) throw new FailureToFollowTheRulesException("id10t");

        // your implementation
    }
}
Nick Larsen
  • 18,631
  • 6
  • 67
  • 96
  • Ok, thanks for your answer, but have you tried saving to database through an EF model? That's where I really run into problems. Also, I don't quite understand your comment about the Htmll helper extension: "have it interface with the prefix scope extensions provided in the project."? What do you mean exactly by that? – Anders Mar 01 '11 at 21:40
  • @Anders once you have the view model back with the data, your problem is no longer with the view or MVC, but instead with the ORM you are using. A simple method to check for new items would be to assume all list items with a particular id are new items, and compare the existing list of Ids against the persisted list to perform your deletes. Or even easier perform deletes as an ajax call. Its all how you want to do it, but at this point you should be able to ask questions about your specific ORM and get better answers. – Nick Larsen Mar 01 '11 at 22:29
  • Ok, but that's what I'm trying to do here, because the question is about the combination: dynamic view and entity framework. I actually already had a view working according to the Sanderson example, but I couldn't get it to save to database through EF (see my previous questions). So I started the question over, trying to find some standard solution to the problem with combining EF with this sort of View... – Anders Mar 02 '11 at 07:05
  • @Anders so if you have are able to pull the data back from the view in a comprehensible manner, stop worrying about that. Next try to save the data as you would want it using only the entity framework... in fact, create a whole new console project, import your EF classes and try to save the data. You might have some questions specific to EF, without the overhead of the existing project. Once you figure out how to get EF to save your data when only using EF and **nothing else**, you can then figure out how to map the view model to the EF model. Subdivide your problem until it is trivial. – Nick Larsen Mar 02 '11 at 14:37
  • Ok, but I really don't have any problems saving in the EF model in "normal" scenarios, such as those created by default templates, with separate views for each simple property. The problem only comes up with the child collections in the same view as the parent object. So saving data per se is not a problem. Please see my previous questions (especially this one: http://stackoverflow.com/questions/5132917/entity-framework-and-mvc-3-the-relationship-could-not-be-changed-because-one-or ) for the entire picture. I've started a bounty on that question... – Anders Mar 02 '11 at 15:48
  • Hi @Anders, Can you please tell me if you found a solution to your problem ? I actually am in the same position and I dont know what to do. – NumberTen Apr 24 '15 at 14:22