简体   繁体   中英

Setup query, navigation properties (Code First) in view (Entity Framework 6 + MVC 5)

What I'm trying to achieve is quite simple. Through code first, I'd like to allow a user to have a series of contacts. Each of them will have the following options: "None", "No encounter yet", and "Client". What I'm looking for, is to add the option selected to the database and retrieve its value.

The problem is that I do not know very well how to setup correctly the relationships. Or I do not know if the query I'm executing is actually managing the relationship.

The approach I'm going after is simple: I create a dropdown list (dictionary based) which retrieves the data from "ExposureResult" table (which is the table in which the options I mentioned previously reside: None, No encounter yet, Client), and shows it to the user at the Contacts creation form.

When submitted, it will give me the ID of the row from the "ExposureResult" table, and I would insert it into the ExposureResultID (which is the property I think I have set as a relationship), so I can call it later.

Later on I execute the following query:

 var query = from c in dbs.ContactsDB where c.IboID == uid select c;
        return query;

Where dbs.ContactsDB is the DB Context of the Contacts model I have implemented and retrieves all the values I'm looking after.

The query variable will return to me the model in an IEnumerable.

Which then, in the .cshtml file I would call it like this:

@foreach (var item in Model) {

item.ExposureResult }

But it wouldn't return me the result I'm expecting, which is getting what does the ID value refers in the ExposureResult, and not the ID itself.

Here's the model

The model is the following:

    public class Contacts
{
    [HiddenInput(DisplayValue=false)]
    [Key]
    public int ContactsID { get; set; }
    [HiddenInput(DisplayValue=false)]
    public int IboID { get; set; }
    public string Name { get; set; }

    [Display(Name="First Time Met")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public string FirstMeet { get; set; }
    public string Phone { get; set; }

    [Display(Name="Date of Contact")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime? DateOfContact { get; set; }

    public string Comments{ get; set; }

    [Display(Name="Next Exposure")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime? NextExposure { get; set; }

    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    [Display(Name = "Next Exposure 2")]
    public DateTime? NextExposure2 { get; set; }

    //This is analogue to SelectedQ from Ibo Model
    //The main purpose is to receive the incoming data from the SelectList
    [NotMapped]
    public string SelectedResult { set; get; }

    [Display(Name = "Result")]
    public int ExposureResultID { get; set; }
    public virtual ICollection<ExposureResults> ExposureResult {get; set;}
    //public virtual ICollection<ExposureResults> ExposureResults { get; set; }
    public virtual ICollection<Ibo> Ibo { get; set; }
}

public class ExposureResults
{
    public int ID { get; set; }
    public string ExposureResult { get; set; }
 }

I'm putting on an image to better explain what I'm trying to achieve: 我想要达到的目标

If i really get what you mean, you need to include "ExposureResult" properties to your query and add a foreign key property to ExposureResults class.

//include
dbs.ContactsDB.Include("ExposureResult") or dbs.ContactsDB.Include(er => er.ExposureResult)

public class ExposureResults {
    public int ID { get; set; }
    public string ExposureResult { get; set; }
    //foreign key property
    public int ContactsID
}

See this article for more information.

I hope that helps!

I managed to do it. I have also posted this concern and answer in the ASP.NET forums:

http://forums.asp.net/p/2014225/5798579.aspx?p=True&t=635498275668626346&pagenum=1

Here it goes:

在此处输入图片说明

First of all, I shall create an int property, whatever name I want. In this case, for consistency, I decided to create the following property:

 public int ExposureResultID { get; set; }

This property will be the foreign key that will have the referenced row of the ExposureResult table/model. But this is not enough. Entity Framework will not know by magic that this is actually the foreign key.

So we then add the following property:

[ForeignKey("ExposureResultID")]
        public virtual ExposureResult ExposureResult { get; set; }

As you can see, I have added the "ExposureResult" type which refers to the table/model/class which will have the data I want to reference to (foreign table).

Please see that I've underlined and bold the "virtual" keyword. It's imperative to put it. This will allow Lazy Loading to work.

Then, as you can see, it has the Data Annotation property "Foreign Key". This is where you tell Entity Framework who is the foreign key. In my case, the property I declared was: ExposureResultID:

在此处输入图片说明

Then, you pass the model to the view, and run a foreach loop:

@foreach (var item in Model) {
     @Html.DisplayFor(modelItem => item.ExposureResult.ExposureResults)

}

This will make Lazy Loading work!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM