Add model with link to model object EFModelFirst

喜你入骨 提交于 2019-12-11 15:37:22

问题


So I have 2 models: Person and Ingredient and the thing I want to accomplish is that anyone can choose an ingredient (through a jQuery autocomplete), input their data and then on create it saves that to the database.

So it would be like this:

    public class Person {

            public int PersonID { get; set; }

            [Required(ErrorMessage="Given name is a required field")]
            [DisplayName("Given name")]
            public string GivenName { get; set; }

            [Required(ErrorMessage="Family name is a required field")]
            [DisplayName("Family name")]
            public string FamilyName { get; set; }

            [Required(ErrorMessage = "Birthdate is a required field")]
            [DisplayFormat(DataFormatString = "{0:d}")]
            public DateTime Birthdate { get; set; }

            [DisplayName("Ingredient")]
            public virtual Ingredient Ingredient { get; set; }
    }

And:

public class Ingredient {
    public int IngredientID { get; set; }

    [Required(ErrorMessage = "Ingredient is a required field")]
    [Remote("IngredientExists", "Person")]
    public string Name { get; set; }

    public virtual ICollection<Person> Persons { get; set; }
}

Now my view currently looks like this: (snippet for just the ingredient part)

    <div class="editor-label">
    @Html.LabelFor(model => model.Ingredient)
</div>
    <div id="ingredients-list" class="editor-field">        
    @Html.EditorFor(model => model.Ingredient.Name)
        @Html.ValidationMessageFor(model => model.Ingredient.Name)
        @ViewBag.IngredientError
</div>

Controller:

//
// POST: /Person/Create

[HttpPost]
public ActionResult Create(Person person) {
    if (ModelState.IsValid) {
        db.People.Add(person);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    person.Ingredient.Name = "";

    return View(person);
}

Now this all works except for 1 thing (a kinda major issue), when I select an ingredient from my dropdown, it saves the person AND creates a new ingredient in the database with a new ID and the same value as the one chosen (ie: a duplicate). Now, I'm quite new to the EF and LINQ so I haven't figured out how to do it just yet. Any ideas/solutions will be greatly appreciated!


回答1:


Assuming that the names are indeed unique then you can just select the ingredient the user choose:

var ingredient = db.Ingredients.Single(i => i.Name == name); //throws exception if more than one ingredient with that name excists
person.Ingredient = ingredient;
db.Persons.Add(person)



回答2:


I would sugguest using the foreign key support. Create an IngredientID property on your person model, and then set the property to the primary key IngredientID from your Ingredient model. Maybe the IngredientID can be bound to the value property of the dropdown items

public class Person {
  public int IngredientID { get; set; }
}



回答3:


If you call this:

context.People.Add(person);

you are saying EF that person is a new entity which must be inserted but in the same time you are saying that all related entities which were not attached to context are new as well.

If you want to add only person you can try this instead:

context.People.Attach(person);
context.Entry(person).State = EntityState.Added;


来源:https://stackoverflow.com/questions/5719122/add-model-with-link-to-model-object-efmodelfirst

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!