Click here to Skip to main content
15,889,281 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
I am having an absolute beast of a time trying to get a pair of one-to-one records to update in Entity Framework. Something that seemingly should not be that hard is not well documented online and seems to be so specialized that it's tough to find a source to thoroughly learn this concept. Let me first start by saying that I have watched this video by MicrosoftImplementing Entity Framework with MVC - Part 3/6 - YouTube[^] and in it is indeed some valuable information. The video does explain that indeed, one-to-one relationships in EF are tricky and that you have to specifically tell EF that you are creating a one-to-one relationship by specifying in the domain class that the foreign key class is both a primary key and a foreign key (see my code below or that video above).

But what I am struggling with here is this concept that a Bar has an Address. I have 2 domain classes: Bar and Address. Inside Bar, there is an Address of type Address and inside Address there is a Bar of type Bar.

The question is, in my controller logic (I am working with MVC), do I need to tell the database to pull a bar out and then update that bar's Address via something like this:

C#
barInDb = _context.Bars.SingleorDefault( b =>b.BarId == id);

barInDb.Address.StreetName = bar.Address.StreetName;


OR Do I need to update the Address class directly like this:

C#
barInDb = _context.Bars.SingleorDefault( b =>b.BarId == id);
addressInDb = _context.Addresses.SingleorDefault(a =>a.BarId == id);

addressInDb.StreetName = bar.Address.StreetName;


In other words, to manage this type of relationship properly, I'm not sure how to edit these properties. The operation is not complicated: I have a form and I want to store the addresses of bars in the address table, while the rest of the bar info in the bar table. When the user edits a bar in the bar edit forum and clicks submit, I want the controller to add the bar info into the Bar table and the bar's address info into the Address table, with the associated BarId so that they can be paired properly. That's it.

The Microsoft video above though uses a lot of scaffolding and automatic assistance and I have not used this. I prefer to write my on code from scratch and have already done so. I have linked to the GitHub for this code in case you would like to actually take a look at my code. For this, please see the BarController,BarForm (in the Views folder), and associated Address and Bar domain models.

Also, see the viewmodel code below:

C#
public class BarFormViewModel
    {
        public Address Address { get; set; }
        public Bar Bar { get; set; }

        public bool IsNew { get; set; }


    }
}


I am passing this viewmodel to my form like so but I have tried many different ways so this is experimental:
C#
public ActionResult Edit(int id)
        {
            
            var bar = _context.Bars.SingleOrDefault(b => b.BarId == id);
            //Make sure that the id actually exists:
            if (bar == null)
            {
                return HttpNotFound();
            }
            if (bar.Address == null)
            {
                bar.Address.BarId = id;

            }
            var viewModel = new BarFormViewModel
            {
                Address = bar.Address,
                Bar = bar,
                IsNew = false
            };


            return View("BarForm", viewModel);
        }


HappyHourBeerList/HappyHourBeerList at master · TheOnlyRealTodd/HappyHourBeerList · GitHub[^]

What I have tried:

I have tried changing the BarForm to use Address.propertyHere as well as use Bar.Address.propertyhere. I have also tried messing with my controller to use both of these formats. In all circumstances, the code runs but the record is not updated.
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900