Many to many relation - have I done it right? - c#

The idea is pretty simple. I have a list of tags. When I create a question I want to add some tags to it.
Models:
public class QuestionModel
{
public int Id { get; set; }
public String Content { get; set; }
public ICollection<TagModeltoQuestionModel> Tags { get; set; }
[NotMapped]
public ICollection<TagModel> AssignedTags { get { return Tags.Select(x => x.Tag).ToList(); } }
public int UserId { get; set; }
}
public class QuestionViewModel // helper - not in database
{
public QuestionModel Model { get; set; }
public ICollection<TagModel> Tags { get; set; }
}
public class TagModel
{
public int Id { get; set; }
public String Name { get; set; }
public ICollection<TagModeltoQuestionModel> Questions { get; set; }
[NotMapped]
public bool Assigned { get; set; }
[NotMapped]
public ICollection<QuestionModel> AssignedQuestions { get { return Questions.Select(x => x.Question).ToList(); } }
}
public class TagModeltoQuestionModel // many to many
{
[Key, Column(Order = 0)]
public int TagId { get; set; }
[Key, Column(Order = 1)]
public int QuestionId { get; set; }
public virtual QuestionModel Question { get; set; }
public virtual TagModel Tag { get; set; }
}
Controller:
[HttpPost]
public ActionResult Edit(QuestionViewModel questionViewModel)
{
if (ModelState.IsValid)
{
_repo.Update(questionViewModel.Model, questionViewModel.Tags); // see repo code below
return RedirectToAction("Index");
}
return View(questionViewModel.Model);
}
Repo:
public void Update(QuestionModel entity, ICollection<TagModel> tags)
{
AssignTags(entity, tags);
Db.Attach(entity);
Db.SaveChanges();
}
private void AssignTags(QuestionModel entity, ICollection<TagModel> tags)
{
tags = tags.Where(x => x.Assigned).ToArray(); // remove unassigned comming form View --> Controller
var linkedTags =
Db.TagsToQuestions.Where(x => x.QuestionId == entity.Id);
var linkedTagsIds = linkedTags.Select(x => x.TagId);
var selectedTagsIds = tags.Select(x => x.Id);
var oldTags = linkedTags.Where(x => !selectedTagsIds.Contains(x.TagId));
var newTags = tags.Where(x => !linkedTagsIds.Contains(x.Id)).Select(x=> new TagModeltoQuestionModel{QuestionId=entity.Id,TagId=x.Id});
foreach (var t in oldTags)
Db.Delete(t);
foreach (var t in newTags)
Db.Add(t);
Db.SaveChanges();
}
This works fine, though I'm not sure if this is the right way to go (in fact I implemented the whole many-to-many logic myself). Is there a smarter way to let EF do the job for me? I dug through a bunch of tutorials, but none of them worked for me.
Additionally I feel that AssignTags method could be written in a better way, so any comments concerning that also appreciated.
EDIT
According to haim770's answer I simplified the model the way he suggested.
My controller now looks like that:
public void Update(QuestionModel entity, ICollection<TagModel> tags)
{
Db.Attach(entity);
//these lines give the same result
//var ids = tags.Select(y => y.Id).ToArray();
//entity.Tags = Db.Tags.Where(x => ids.Contains(x.Id)).ToArray();
tags.ForEach(x => Db.Attach(x));
entity.Tags = tags;
Db.SaveChanges();
}
SaveChanges results in an error:
An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.
inner:
{"A duplicate value cannot be inserted into a unique index. [ Table name = TagModelQuestionModels,Constraint name = PK_TagModelQuestionModels ]
So how to implement it correctly?

You do not need the TagModeltoQuestionModel class. You could model many-to-many relations like this:
public class QuestionModel
{
//....
public ICollection<TagModel> Tags { get; set; }
}
public class TagModel
{
//....
public ICollection<QuestionModel> Questions { get; set; }
}
Question holds a reference to many Tags and each Tag holds a reference to many Questions.
The whole point of Entity Framework (like any other ORM) is to spare you from having to model your objects and their relations in a database-like way but rather let you model it in a pure Object Oriented way then letting the ORM do the 'dirty work' of intermediate-tables, foreign keys etc...

Related

How do I add and update items using Entity Framework Core 5 that have many to many relationships?

I've been struggling with this all evening and still don't fully understand how Entity Framework Core works with many to many relationships.
I have a TransportProvider class and a Tag class. It's a many to many relationship. When adding a new TransportProvider you can assign tags. If the tag already exists in the database I'd like to add that existing tag, otherwise I'd like to insert a new tag. This is what I have for my TransportProvider class:
public class TransportProvider
{
public int ID { get; set; }
[Display(Name = "Company name")]
[Required]
[StringLength(200)]
public string CompanyName { get; set; }
... standard properties
public bool Disabled { get; set; }
[NotMapped]
public string SelectedTags { get; set; }
public ICollection<Tag> Tags { get; set; }
}
My tag class:
public class Tag
{
public int ID { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
public ICollection<TransportProvider> TransportProviders { get; set; }
}
And this is my controller function that creates a new transport provider:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,CompanyName,ContactName,ContactTelephone1,ContactTelephone2,ContactEmail,CompanyWebsite,AddressLine1,AddressLine2,Suburb,Province,PostCode,Country,Lat,Lng,SelectedTags,Notes,Disabled")] TransportProvider transportProvider)
{
if (ModelState.IsValid)
{
var selectedTags = !string.IsNullOrEmpty(transportProvider.SelectedTags) ? transportProvider.SelectedTags.Split(',') : new string[0];
_context.TransportProviders.Add(transportProvider);
foreach (var selectedTag in selectedTags)
{
var tag = _context.Tags.SingleOrDefault(t => t.Name.ToLower() == selectedTag);
if (tag == null)
{
tag = new Tag();
tag.Name = selectedTag;
}
transportProvider.Tags.Add(tag);
}
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(transportProvider);
}
and finally my context class:
public class AntelopeContext : DbContext
{
public AntelopeContext(DbContextOptions<AntelopeContext> options) : base(options)
{
}
public DbSet<TransportProvider> TransportProviders { get; set; }
public DbSet<Tag> Tags { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TransportProvider>().ToTable("TransportProvider");
modelBuilder.Entity<Tag>().ToTable("Tag");
}
}
If I try and execute this code I get a NullReferenceException for the line:
transportProvider.Tags.Add(tag);
I don't know why this is so difficult to do. All I want to do is add tags to a transport provider. If the tag is new it needs to insert a new tag record. If not then it just has to link the existing tag.
How do I do this?
Thanks
Many to many relationships require a collection navigation property on both sides. They will be discovered by convention like other types of relationships.
public class TransportProvider
{
public int TransportProviderId { get; set; }
public string CompanyName { get; set; }
public bool Disabled { get; set; }
public ICollection<Tag> Tags { get; set; }
}
public class Tag
{
public int TagId { get; set; }
public string Name { get; set;}
public ICollection<TransportProvider> TransportProviders { get; set; }
}
The way this relationship is implemented in the database is by a join table that contains foreign keys to both TransferProvider and Tag. For example this is what EF will create in a relational database for the above model.
CREATE TABLE [TransportProvider] (
[TransportProviderId] int NOT NULL IDENTITY,
[CompanyName] nvarchar(max) NULL,
[Disable] bit NULL,
CONSTRAINT [PK_TransportProvider] PRIMARY KEY ([TransportProviderId])
);
CREATE TABLE [Tag] (
[TagId] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
CONSTRAINT [PK_Tag] PRIMARY KEY ([TagId])
);
CREATE TABLE [TransportProviderTag] (
[TransportProviderId] int NOT NULL,
[TagId] int NOT NULL,
CONSTRAINT [PK_TransportProviderTag] PRIMARY KEY ([TransportProviderId], [TagId]),
CONSTRAINT [FK_TransportProviderTag_TransportProviders_TransportProviderId] FOREIGN KEY ([TransportProviderId]) REFERENCES [TransferProviders] ([TransferProviderId]) ON DELETE CASCADE,
CONSTRAINT [FK_TransportProviderTag_Tags_TagId] FOREIGN KEY ([TagId]) REFERENCES [Tags] ([TagId]) ON DELETE CASCADE
);
Internally, EF creates an entity type to represent the join table that will be referred to as the join entity type.
This is a code first approach.
You have first to create TransferProvider and Tag, and then add what row with them in TransferProviderTag table
Since you didn't bind the Tags property, it will default be null, you need to initialize the Tags in TransportProvider firstly.
public async Task<IActionResult> Create([Bind("ID,CompanyName,ContactName,ContactTelephone1,ContactTelephone2,ContactEmail,CompanyWebsite,AddressLine1,AddressLine2,Suburb,Province,PostCode,Country,Lat,Lng,SelectedTags,Notes,Disabled")] TransportProvider transportProvider)
{
transportProvider.Tags = new List<Tag>();
//...
}
Finally! I got it working. I'm not sure this is the 'correct' way, but it seems to work.
I was under the impression that EF Core 5 didn't require joining tables in many-to-many relationships. However when I tried to execute without a joining table I was getting an error about a joining table not being present. I therefore added one as suggested.
I then manually created the TransportProvider, manually checked for a Tag and created if it didn't exist, then manually entered the joining table record. I still feel this probably isn't the most efficient way of doing things, but it works. Code in case anyone is interested:
public async Task<IActionResult> Create([Bind("ID,CompanyName,ContactName,ContactTelephone1,ContactTelephone2,ContactEmail,CompanyWebsite,AddressLine1,AddressLine2,Suburb,Province,PostCode,Country,Lat,Lng,SelectedTags,Notes,Disabled")] TransportProvider transportProvider)
{
if (ModelState.IsValid)
{
var selectedTags = !string.IsNullOrEmpty(transportProvider.SelectedTags) ? transportProvider.SelectedTags.Split(',') : new string[0];
transportProvider.TransportProviderTags = new List<TransportProviderTag>();
_context.TransportProviders.Add(transportProvider);
await _context.SaveChangesAsync();
foreach (var selectedTag in selectedTags)
{
var tag = _context.Tags.SingleOrDefault(t => t.Name.ToLower() == selectedTag);
if (tag == null)
{
tag = new Tag();
tag.Name = selectedTag;
_context.Tags.Add(tag);
await _context.SaveChangesAsync();
}
var tpt = new TransportProviderTag();
tpt.TransportProviderID = transportProvider.ID;
tpt.TagID = tag.ID;
transportProvider.TransportProviderTags.Add(tpt);
await _context.SaveChangesAsync();
}
return RedirectToAction(nameof(Index));
}
return View(transportProvider);
}
Updated context class:
public class AntelopeContext : DbContext
{
public AntelopeContext(DbContextOptions<AntelopeContext> options) : base(options)
{
}
public DbSet<TransportProvider> TransportProviders { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<TransportProviderTag> TransportProviderTags { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TransportProvider>().ToTable("TransportProvider");
modelBuilder.Entity<Tag>().ToTable("Tag");
modelBuilder.Entity<TransportProviderTag>().ToTable("TransportProviderTag");
modelBuilder.Entity<TransportProviderTag>()
.HasKey(tpt => new { tpt.TransportProviderID, tpt.TagID });
modelBuilder.Entity<TransportProviderTag>()
.HasOne(tpt => tpt.TransportProvider)
.WithMany(tp => tp.TransportProviderTags)
.HasForeignKey(tpt => tpt.TransportProviderID);
modelBuilder.Entity<TransportProviderTag>()
.HasOne(tpt => tpt.Tag)
.WithMany(t => t.TransportProviderTags)
.HasForeignKey(tpt => tpt.TagID);
}
}
And thanks #MilutinSpaic and #mj1313 for steering me in the right direction. Hopefully this will help someone else

How to hide items, in an API reply, from a db query?

I'm currently using MVC with EF to have a small server with API querying a SQL database. But in the API reply I'm not able to hide some parameters.
The main object
public class AssetItem
{
[Key]
public Int32 AssetId { get; set; }
public String AssetName { get; set; }
public int OdForeignKey { get; set; }
[ForeignKey("OdForeignKey")]
public OperationalDataItem OperationalDataItem { get; set; }
}
The other one:
public class OperationalDataItem
{
[Key]
public Int32 OperationalDataId { get; set; }
public String Comunity { get; set; }
public List<AssetItem> AssetItems { get; set; }
}
From what I have read, this should be ok, I have also set the context:
public AssetContext(DbContextOptions<AssetContext> options) : base(options)
{}
public DbSet<AssetItem> AssetItems { get; set; }
public DbSet<OperationalDataItem> OperationalDataItems { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AssetItem>().HasOne(p =>
p.OperationalDataItem).WithMany(b => b.AssetItems).HasForeignKey(p =>
p.OdForeignKey);
}
And the seeding in program.cs
context.AssetItems.Add(
new AssetItem { AssetName = "Test test", OdForeignKey = 1,
OperationalDataItem =
new OperationalDataItem {Comunity = "Comunity1" }});
So calling the API this results in:
{ "assetId":3,
"assetName":"Test test",
"odForeignKey":1,
"operationalDataItem":null }
From what I read this is because of the lazy loading, how can I hide the result operationalDataItem?
In case is not possible i have of course try to query for it and give it back and it give something like:
{ "assetId":3,
"assetName":"Test test",
"odForeignKey":1,
"operationalDataItem":
{ "operationalDataId":1,
"comunity":"Comunity1",
"assetItems":[
But in this case I would like to hide "assetsItems" in the reply to the FE.
How can I hide those parameters?
The API is quite simple, just an example code:
var todoItem = await _context.AssetItems.FindAsync((Int32)id);
var item = _context.OperationalDataItems.Find((Int32)todoItem.OdForeignKey);
todoItem.OperationalDataItem = item;
return todoItem
If you want to fetch data from the database, but you only want to fetch some properties, use Select. Usually this is more efficient than using Find, because you'll only transfer the data that you actually plan to use.
To fetch some properties of the assetItem that has primary key assetItemId:
var result = dbContext.AssetItems
.Where(assetItem => assetItem.AssetItmId = assetItemId)
.Select(assetItem => new
{
// Select only the properties that you plan to use
Id = assetItem.AssertItemId,
Name = assetItem.Name,
OperationalData = new
{
// again, select only the properties that you plan to use
Id = assetItem.OperationalData.OperationalDataId,
Community = assetItem.OperationalData.Community,
},
})
.FirstOrDefault();
Or the other way round:
Fetch several properties of all (or some) OperationalDataItems, each with some properties of all (or some) of its AssetItems:
var result = dbContext.OperqationalDataItems
.Where(operationalDataItem => ...) // only if you don't want all
.Select(operationalDataItem => new
{
Id = operationalDataItem.Id,
Community = operationalDataItem.Community
AssetItems = operationalDataItem.AssetItems
.Where(assetItem => ...) // only if you don't want all its assetItems
.Select(assetItem => new
{
// Select only the properties you plan to use:
Id = assetItem.Id,
...
// not useful: you know the value of the foreign key:
// OperationalDataId = assetItem.OperationalDataId,
})
.ToList();
})
.ToList(); // or: FirstOrDefault if you expect only one element
Entity framework knows your one-to-many relation and is smart enough to know which (group-)join is needed for your query.
Some side remarks
You've declare your many-relation a List<AssetItem>. Are you sure that operationalDataItem.AssetItems[4] has a defined meaning? Wouldn't it be better to stick to the entity framework code first conventions? This would also eliminate the need for most attributes and / or fluent API
public class OperationalDataItem
{
public int Id { get; set; }
public String Comunity { get; set; }
...
// Every OperationalDataItem has zero or more AssetItems (one-to-many)
public virtual ICollection<AssetItem> AssetItems { get; set; }
}
public class AssetItem
{
public int Id { get; set; }
public String Name { get; set; }
...
// every AssetItem belongs to exactly one OperationalDataItem, using foreign key
public int OperationDataItemId { get; set; }
public virtual OperationalDataItem OperationalDataItem { get; set; }
}
In entity framework the columns of a table are represented by the non-virtual properties. The virtual properties represent the relations between the tables (one-to-many, many-to-many)
Because I stuck to the conventions, no attributes nor fluent API is needed. Entity framework is able to detect the one-to-many relation and the primary and foreign keys. Only if I am not satisfied with the names or the types of the columns I would need fluent API.

Deleting Child Entries when deleting parent

I've read around various posts but none seem to match my issue.
I need to delete child entries linked to a foreignkey when the parent is deleted.
Currently I have this code:
public async Task UpdateLineItemByOrderLineId(int orderLineId, int newQuantity)
{
var clientBasket = await GetBasketAsync();
var lineItem = clientBasket.OrderLines.FirstOrDefault(x => x.OrderLineId == orderLineId);
if (newQuantity == 0)
{
_orderLinesRepository.Delete(lineItem);
_orderLinesRepository.Save();
}
and this linked to the following repository
public class OrderLinesRepository : GenericRepository<OrderLine>, IOrderLinesRepository
{
public OrderLinesRepository(IDbContextFactory dbContextFactory)
: base(dbContextFactory)
{
}
}
Posts seem to mention entity framework etc and being as I'm learning C# from a solution handed to me to bring to completion I don't see matching code that reflects EF.
I don't necessarily need to delete the child elements but simply set the ForeignKey to null. One thing to note is that I can have multiple child entries linked to the ForeignKey.
What is the correct implementation to achieve the above?
Edit: Foreign Key Assignment
namespace TSW.Ecommerce.Data.Api
{
public class OrderDelegate
{
[Key]
public int OrderDelegateId { get; set; }
[ForeignKey("OrderLineId")]
public virtual OrderLine OrderLine { get; set; }
public int? OrderLineId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
}
Correct solution is:
foreach (var m in lineItem.DelegatesList.Where(f=>f.OrderLineId == orderLineId))
{
lineItem.DelegatesList.Remove(m);
}

Entity framework cannot seem to create relationship

The entity framework isn't super new to me, however is confusing as I continue to expand my data models. I am attempting to create a class that has an array of another class. Class A or County.cs has a list of Class B or Product.cs
I cannot seem to create write these classes in a way that when you ask for context.counties you also get the array of products attached to it.
Class A or County.cs
public class County
{
[Key]
public int ID { get; set; }
public String Name { get; set; }
public List<Product> Products { get; set; } = new List<Product>();
[NotMapped]
public DateTime firstAppearance {
get {
var data = (from obj in Products orderby obj.Date descending select obj.Date).FirstOrDefault();
if (this.softwareIn)
{
return data;
}
else
{
var date = new DateTime(1,1,1);
return date;
}
}
set {
this.firstAppearance = value;
}
}
[NotMapped]
public bool softwareIn {
get {
return Products.Count() >= 1;
}
set {
this.softwareIn = value;
}
}
}
Class B or Product.cs
public class Product
{
[Key]
public int ID { get; set; }
public String Name { get; set; }
public DateTime Date { get; set; }
[NotMapped]
public DateTime DateUtc {
get {
return getUtcDate();
}
set {
this.DateUtc = value;
}
}
public DateTime getUtcDate() {
return this.Date.ToUniversalTime();
}
}
I just don't understand and haven't created enough of 1:M relations in the entity framework. Why cannot I do something like this and have it work all the time? The first time I run this I get the type of data I expect, the xx county has a product. However if I remove all this and just return the context.counties I get nothing in the products array.
[Route("Counties")]
public object GetCounties() {
var data = new County() {
Name = "xxx",
};
data.Products.Add(new Product() { Name="Cool Software", Date = DateTime.Now});
db.Counties.Add(data);
db.SaveChanges();
var da = db.Counties.ToList();
return db.Counties;
}
The reason you have having this issue is because the foreign keys are not correctly configured. Take a look at your database and look at the foreign keys. For Entity Framework to understand the relationships properly, you must mark related entities as virtual. So do this:
public virtual List<Product> Products { get; set;}
And then in your Product class add the navigation property back to the parent County:
public virtual County County { get; set;}
I found this tutorial really good:
http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx
Hope this helps.

Entity framework relationships

I have these three entities:
public class Dog
{
public int DogId { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public bool Checked { get; set; }
public string DogImage { get; set; }
public virtual ICollection<Result> Results { get; set; }
}
public class Event
{
public int EventId { get; set; }
public string EventName { get; set; }
public string EventLocation { get; set; }
public string EventType { get; set; }
public string EventDate { get; set; }
public virtual ICollection<Result> Results { get; set; }
}
public class Result
{
public int ResultId { get; set; }
public int Track { get; set; }
public int Obedience { get; set; }
public int Protection { get; set; }
[ForeignKey("Dog")]
public int DogId { get; set; }
public virtual Dog Dog { get; set; }
[ForeignKey("Event")]
public int EventId { get; set; }
public virtual Event Event { get; set; }
}
I´ve been getting help from here before in order to set it up like this.
Entity Framework errors when trying to create many-to-many relationship
So the way it is now I guess the result is the "glue" that ties these classes together containing foreign keys to the two other tables.
What I have been trying to achieve for days now is to:
Create an event.
Add dogs to the event.
Add results to the dogs participating in the choosenEvent.
Lets say I create an event like this:
[HttpPost]
public ActionResult CreateEvent(Event newEvent)
{
newEvent.EventDate = newEvent.EventDate.ToString();
_ef.AddEvent(newEvent);
return View();
}
Now I guess the next step would be to add a list of dogs to this event and in order to do that I need to somehow use my result-class since that's the "glue"-class. Please let me know if I'm even on the right track here.
It is not really a good idea to do many to many relationships like how you've done. See here
In order to get a proper many to many relationship, mapped in the proper way in the database, that doesn't have pitfalls, I would try it this way:
public class Dog {}
public class Event {}
public class Result {}
// This is a linking table between Dog and Results
public class DogResult
{
public int Id {get;set;}
public int DogId {get;set;}
public int ResultId {get;set;}
}
// This is a linking table between Events and Results
public class EventResult
{
public int Id {get;set;}
public int EventId {get;set;}
public int ResultId {get;set;}
}
When you now write your query you can do this:
using (var context = new DbContext())
{
var dogs = context.Dogs();
var dogResults = context.DogResults();
var results = context.Results();
var dogsAndResults = dogs.Join(
dogResults,
d => d.Id,
r => r.DogId,
(dog, dogResult) => new { dog, dogResult })
.Join(
results,
a => a.dogResult.ResultId,
r => r.Id,
(anon, result) => new { anon.dog, result });
}
It is a bit nasty looking, but it will give you back a list of anonymous objects containing a Dog and its related Result. But obviously it would be better to do this in a stored proc:
using (var context = new DbContext())
{
var results = context.Database.ExecuteStoreQuery<SomeResultDto>("SELECT * .... JOIN ... ");
}
This is cleaner, because you are using SQL.
This is a more complex way of dealing with it. But far more performant, especially if you understand fully how entity framework executes LINQ.
Obviously if you want to create these links:
using (var context = new DbContext())
{
context.Dogs.AddRange(dogs); // dogs being a list of dog entities
context.Results.AddRange(results); // events being a list of results entities
context.DogResults.AddRange(dogResults); // a list of the links
}
It is completely up to you how you create these links. To turn this into a sproc as well, you want to create some custom User Defined Table Types and use them as a Table Value Parameter.
var dogResults = dogs.SelectMany( d => results.Select ( r => new DogResult { DogId = d.Id, ResultId = r.Id } ) );
That is a beast of a LINQ query and basically it gets every dog and links it to every result. Run it in LinqPad and Dump the values.
I've only done this using the fluent method (when I was learning I found you can do everything in fluent, but not with annotations, so I've not looked into them), the following creates a many to many between my Unit entity and my UnitService entity:
modelBuilder.Entity<Unit>()
.HasMany<UnitService>(u => u.Services)
.WithMany(us => us.Units);
This code is in the protected override void OnModelCreating(DbModelBuilder modelBuilder) method.
In your case Event is Unit and Dog is UnitService.
Oh ooops, you don't need that at all, your 'join' table is your results table, in my case I don't care about the join table so its all hidden.
Maybe something like:
modelBuilder.Entity<Result>()
.HasMany<Event>(e => e.Results);
modelBuilder.Entity<Result>()
.HasMany<Dog>(d => d.Results);

Categories

Resources