0

It should be something simple, not sure why I couldn't find the solution on the web. Maybe it's specific to EF6 or ASP Identity or, maybe I'm entering wrong search key words.

To simplify things, let's say I have two model classes Teacher and Kid; One kid can be assigned only to one teacher, but one teacher can have many kids. It's multi-user environment, so each Kid and each Teacher belong to particular user. As I'm using code first, my database is constructed from these model classes:

public class Kid
{
    [Required]
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public virtual Teacher { get; set; }    
    [Required]
    public virtual ApplicationUser User { get; set; }
}

public class Teacher
{
    [Required]
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    public virtual ICollection<Kid> Kids { get; set; }
    [Required]
    public virtual ApplicationUser User { get; set; }
    }

I have a view for adding new kid with: Textbox for Kid's name; Dropdown with list of Teachers

So, I'm creating a data transfer object, specifically for that view:

public class AddNewKidViewDTO
{
    public string Name {get; set;}
    public IEnumerable<SelectListItem> Teachers { get; set; }
    public int SelectedTeacherId { get; set; }
}

Form gets submitted and I get my populated AddNewKidViewDTO model.

Now, I need to insert a new Kid into the database. So, I map AddNewKidViewDTO properties to my Kid model properties one by one:

public void InsertNewKid {AddNewKidViewDTO addNewKidViewDTO}
{
    Kid kid = new Kid();
    kid.Name = AddNewKidViewDTO.Name;
    // here comes the question. How do I set Kid.Teacher and Kid.User?
}

UPDATE 1

I'm NOT asking how to get selected teacher id. I need to know how to assign navigation property to model object (using that id).

UPDATE 2:

If I get current user object like this:

ApplicationUser user = usermanager.FindById(User.Identity.GetUserId<int>());

And then attach it to Kid:

Kid.User = user;

On Kid insert, it throws exception:

The member with identity 'mynamespace.DAL.Kid_User' does not exist in the metadata collection.

Any help appreciated.

Valeriya
  • 1,067
  • 2
  • 16
  • 31

2 Answers2

0
AddNewKidViewDTO.Teachers.FirstOrDefault(t=>t.Selected).Value

above code will give selected teacher id.

Can u post the Kid model

  • Dinesh, kindly read the question one more time. Kid model is posted. I don't need selected teacher id. I have it. I need to know how to assign foreign key property (navigation property) to a model object. – Valeriya Mar 17 '15 at 13:41
  • Sorry Lera, i misunderstood the question and not saw the Kid model. If u need teacher model u can get the model like this `Teacher.FirstOrDefault(s=>s.Id == AddNewKidViewDTO.Teachers.FirstOrDefault(t=>t.Selected).Value)` Then assign the returned value to `Kid.Teacher` – Dinesh Kumar Mar 18 '15 at 07:29
0
public void InsertNewKid {AddNewKidViewDTO addNewKidViewDTO}
{
    Kid kid = new Kid();
    kid.Name = AddNewKidViewDTO.Name;
    kid.Teacher = yourdatacontext.Teachers.Find(addNewKidViewDTO.SelectedTeacherId);
    // The context.Savechanges() can be done either here or in your actionlink
}

You should be able to do the same with user assuming you know the appropriate id. It is also possible to search it using the .where method if you don't have the id in hand. Exemple:

kid.User = context.Users.Where(x => x.Name == "whatever string").FirstOrDefault<User>();

This can be done with any attribute.

Considering your database has properly generated the 1 to many relationship, the kid should automatically be added into the "parent" teacher's kids collection.

However I am concerned about the [Required] for

public virtual ICollection<Kid> Kids { get; set; }

A kid is dependant on the existence of a teacher however I don't really see the point of the dependency being both ways.

Teacher constructor to be added right into the model class:

public Teacher()
        {
            this.Kids = new HashSet<Kid>();
        }
Simon
  • 51
  • 6
  • if you ever use one to one or many to many relationships, I suggest looking up the model builder doc https://msdn.microsoft.com/en-US/data/jj591620. – Simon Mar 17 '15 at 20:47
  • I've done some research, It's not advised to access database in order to get current user object. It can be done via "ApplicationUser user = usermanager.FindById(User.Identity.GetUserId());" However, attaching this object to Kid throws exception. Btw, you are right about [Required] for Kid collection, I'll remove it now – Valeriya Mar 18 '15 at 07:38
  • Could it be a null exception due to the kid collection not being initialized? We usually tend to initialize collections in the model constructor as edited above. – Simon Mar 18 '15 at 12:07