Entity Framework : EF Designer from DB : Partial Class not working as expected

I do not understand why this works sometimes and sometimes not.

I am trying to configure partial class to add a few more fields, but the controller is not able to detect the new fields added to the partial class and the view throws the following error:

The associated metadata type for type ‘WebApplication1.Models.Table’ contains the following unknown properties or fields: countryList, selectedCountryList. Please make sure that the names of these members match the names of the properties on the main type.

So the problem is with the partial class. EF is not able to detect the new fields added to the partial class.

Model class generated by EF

namespace WebApplication1.Models
{
    using System;
    using System.Collections.Generic;
    
    public partial class Table
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Gender { get; set; }
        public Nullable<bool> Java { get; set; }
        public Nullable<bool> Eng { get; set; }
        public string cityCode { get; set; }
    
        public virtual Country Country { get; set; }
    }
}

namespace WebApplication1.Models
{
    using System;
    using System.Collections.Generic;
    
    public partial class Country
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Country()
        {
            this.Tables = new HashSet<Table>();
        }
    
        public long cityId { get; set; }
        public string cityCode { get; set; }
        public string cityName { get; set; }
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Table> Tables { get; set; }
    }
}

Partial class
namespace WebApplication1.Models
{
    [MetadataType(typeof(TableMetaData))]
    public partial class Table
    {
    }

    public class TableMetaData
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Gender { get; set; }
        public Nullable<bool> Java { get; set; }
        public Nullable<bool> Eng { get; set; }
        public string cityCode { get; set; }
    
        public virtual Country Country { get; set; }

        public SelectList countryList { get; set; }
        public string[] selectedCountryList { get;set; }
    }
}

This is my controller, the reason behind using viewBag.list is that the controller is not able to detect the partial class fields (i.e countryList).

So, I am using ViewBag.list now but by right I should be using item.countryList

public ActionResult Create(int? id)
{
    ACDEntities1 db = new ACDEntities1();
    var item = db.Tables.Find(id);
    var CList = db.Countries.ToList();
    viewBag.countryList = new SelectList(CList, "CityCode", "cityName");
    //should use the following
    //item.countryList = new SelectList(CList, "CityCode", "cityName");

    return View(item);
}

View, here I am trying to use the field selectedCountryList of my partial class but it throws an error.
@Html.DropDownListFor(model => model.selectedCountryList, (IEnumerable<SelectListItem>)viewBag.countryList, "select city", new { @class = "form-control chosen-select", @multiple = true})

// should use this
// @Html.DropDownListFor(model => model.selectedCountryList, //(IEnumerable<SelectListItem>)Model.countryList, "select city", new { @class = "form-control //chosen-select", @multiple = true})

WORKING CODE

Partial class

namespace WebApplication1.Models
{
    [MetadataType(typeof(TableMetaData))]
    public partial class Table
    {
        [NotMapped]
        public SelectList countryList { get; set; }
        [NotMapped]
        public string[] selectedCountryList { get;set; }
    }

    public class TableMetaData
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Gender { get; set; }
        public Nullable<bool> Java { get; set; }
        public Nullable<bool> Eng { get; set; }
        public string cityCode { get; set; }
    
        public virtual Country Country { get; set; }

    }
}

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I believe you’re doing it wrong with your partial class. All the partial class parts from the various physical files they’re specified in are joined together into one class definition – so your additional field must be in the partial class itself – not in the “metadata” class.

Try this:

namespace WebApplication1.Models
{
    public partial class Table
    {
        /* you cannot re-define those in your second "partial class" bit.....
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Gender { get; set; }
        public Nullable<bool> Java { get; set; }
        public Nullable<bool> Eng { get; set; }
        public string cityCode { get; set; }
    
        public virtual Country Country { get; set; }
        */ 

        public SelectList countryList { get; set; }
        public string[] selectedCountryList { get;set; }
    }
}

Since those partial parts are joined together – of course, you cannot have something defined in your hand-written part that’s already defined in the generated part.

The [MetadataType(typeof(TableMetaData))] mechanism was designed to give you the opportunity to add additional metadata to an existing class (e.g. one that’s code-generated) in order to add things like data annotations ([Required], [StringLength] etc.) – but that metadata mechanism isn’t designed to extend the partial class and add additional properties to it

Method 2

It’s because of your partial class location and name
create a folder named Partial or …
and create your partial class with the exact name of the main class and place your custom properties in there

  • partial class name must be the exact name of main class
  • change the partial class namespace to WebApplication1.Models, not WebApplication1.Models.your folder name

Best regards


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x