Entity framework relationships

后端 未结 2 1269
轮回少年
轮回少年 2021-01-26 15:08

I have these three entities:

public class Dog
{
    public int DogId { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    publ         


        
2条回答
  •  天命终不由人
    2021-01-26 15:41

    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("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.

提交回复
热议问题