markai markai - 2 months ago 14
ASP.NET (C#) Question

EF6 creates new entity instead of setting just a reference

I'd like to save a List of flags for each event. In order to get this done I'm using the following method in my Controller:

public ActionResult CreateEvent(Models.Event newEvent)
{
if(!string.IsNullOrEmpty(Request.Form["flag"]))
{
string[] idArr = Request.Form["flag"].Split(',');
foreach(string idString in idArr)
{
int id = idString.ToInt32();
newEvent.Flags.Add(_applicantRepository.GetFlagByID(id));
}
}
_applicantRepository.SaveEvent(newEvent);
}


In my ApplicantRepository I use the following methods:

public void SaveEvent(Event ev)
{
using (var dbCtx = new VisitorRegistrationContext())
{
dbCtx.Events.AddOrUpdate(ev);
dbCtx.SaveChanges();
}
}

public Models.Flag GetFlagByID(int id)
{
using (var dbCtx = new VisitorRegistrationContext())
{
Models.Flag flag = dbCtx.Flags.Find(id);
return flag;
}
}


Unfortunately, each time I save an Event some new flags will be created. Even though they already exist (with the same id).

enter image description here

These are my models:

public class Event
{
public Event()
{
Users = new List<Usr>();
Type = new EventType();
Flags = new List<Flag>();
}

public int ID { get; set; }

[Required]
[Display(Name = "Event")]
public string EventName { get; set; }
public string Comment { get; set; }

[Required]
public EventType Type { get; set; }
public ICollection<Flag> Flags { get; set; }
}


and

public class Flag
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool IsInactive { get; set; }

public virtual ICollection<Event> Events { get; set; }


}


How can I tell EF to simple set the reference in my intermediate table called FlagEvent?

Jim Jim
Answer

You need to use the same context, for example:

public void CreateEvent(Event newEvent)
{
    var flags = "1,2,3";
    string[] idArr = flags.Split(',');
    using (var ctx = new Context())
    {
        foreach (string idString in idArr)
            newEvent.Flags.Add(ctx.GetFlagByID(Convert.ToInt32(idString)));
        ctx.Events.AddOrUpdate(newEvent);
        ctx.SaveChanges();
    }
}