I have the following classes (I am only showing the properties that matter):
public class TypeLocation
{
[Key]
public int Id {get; set;}
public string Country {get; set;}
public string State {get; set;}
public string County {get; set;}
public string City {get; set;}
public List<Offer> Offers {get; set; }
public TypeLocation()
{
this.Offers = new List<Offer>();
}
}
public class Offer
{
public int Id { get; set; }
public ICollection<TypeLocation> LocationsToPublish { get; set; }
}
This creates the following in the database:
My Question/Problem
The TypeLocations
table is prepopulated with a static list of country/state/county/city records, one or many of them can be associated with the Offer in LocationsToPublish
property. When I try to add a location, using the following code, Entity Framework adds a NEW record in the TypeLocation
table and then makes the association by adding a record in the OfferTypeLocations
table.
public static bool AddPublishLocation(int id, List<TypeLocation> locations)
{
try
{
using (AppDbContext db = new AppDbContext())
{
Offer Offer = db.Offers
.Include("LocationsToPublish")
.Where(u => u.Id == id)
.FirstOrDefault<Offer>();
//Add new locations
foreach (TypeLocation loc in locations)
{
Offer.LocationsToPublish.Add(loc);
}
db.SaveChanges();
}
return true;
}
catch
{
return false;
}
}
I don't want a new record added to the TypeLocations
table, just a relational record creating an association in the OfferTypeLocations
table. Any thoughts on what I am doing wrong?
Solution
Thanks to @Mick who answered below, I have found the solution.
public static bool AddPublishLocation(int id, List<TypeLocation> locations)
{
try
{
using (AppDbContext db = new AppDbContext())
{
Offer Offer = db.Offers
.Include("LocationsToPublish")
.Where(u => u.Id == id)
.FirstOrDefault<Offer>();
//Add new locations
foreach (TypeLocation loc in locations)
{
//SOLUTION
TypeLocation ExistingLoc = db.AppLocations.Where(l => l.Id == loc.Id).FirstOrDefault<TypeLocation>();
Offer.LocationsToPublish.Add(loc);
}
db.SaveChanges();
}
return true;
}
catch
{
return false;
}
}
What happens is, using the existing AppDbContext, I retrieve an existing record from the TypeLocations table (identified here as AppLocations
) and then Add it to the LocationsToPublish entity.
The key is that I was to use the current AppDbContext (wrapped with the Using() statement) for all the work. Any data outside of this context is purely informational and is used to assist in the record lookups or creation that happen within the AppDbContext context. I hope that makes sense.
The TypeLocations are being loaded from a different AppDbContext, they are deemed new entities in the AppDbContext you're constructing within your method. To fix either:-
I'd choose 2:-
public static bool AddPublishLocation(AppDbContext db, int id, List<TypeLocation> locations)
{
try
{
Offer Offer = db.Offers
.Include("LocationsToPublish")
.Where(u => u.Id == id)
.FirstOrDefault<Offer>();
//Add new locations
foreach (TypeLocation loc in locations)
{
Offer.LocationsToPublish.Add(loc);
}
db.SaveChanges();
return true;
}
catch
{
return false;
}
}
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.