简体   繁体   中英

Entity Framework Many to Many Relationship returning Null

I developed and uploaded a web service to Azure using Entity Framework 6.1.3 with MVC design pattern.

So let's imagine I have a Workshop that can have many Clients and a Client that can have many Workshops.

So far my results have been null, empty values and some times correct values but without the relationship (no clients inside my workshop, and the other way around).

This is what I have at this point:

public class Workshop
{
    public Workshop()
    {
        this.Clients = new HashSet<Client>();
        this.ModuleSets = new HashSet<ModuleSet>();
    }

    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    public virtual ICollection<Client> Clients { get; set; }
    public virtual ICollection<ModuleSet> ModuleSets { get; set; }
}

public class Client
{
    public Client()
    {
        this.Workshops = new HashSet<Workshop>();
        this.Vehicles = new HashSet<Vehicle>();
    }

    public int Id { get; set; }
    [Required]
    public string Name { get; set; }

    public virtual ICollection<Workshop> Workshops { get; set; }
    public virtual ICollection<Vehicle> Vehicles { get; set; }
}

Yes I have more relations going on at the same time.

Since that alone was not giving me anything, I added some Fluent Api, like this:

modelBuilder.Entity<Workshop>().
             HasMany(c => c.Clients).
             WithMany(p => p.Workshops).
             Map(
              m =>
              {
                  m.MapLeftKey("Workshop_Id");
                  m.MapRightKey("Client_Id");
                  m.ToTable("WorkshopClients");
              });

The names that are shown are the ones that are in the table WorkshopClients (auto generated by entity framework).

I also read this article to make sure I was doing the right thing when it came to Fluent API.

How to define Many-to-Many relationship through Fluent API Entity Framework?

And this is my simple request on the client:

var request = new RestRequest("api/Workshops") { Method = Method.GET };
var workshopList = await api.ExecuteAsync<List<Workshop>>(request);

API/Workshops method:

// GET: api/Workshops
public IQueryable<Workshop> GetWorkshops()
{
    return db.Workshops;
}

It looks like you are not using lazy loading or that part is lost when you pass the data over the API. Make sure you tell your API to include the child objects:

public IQueryable<Workshop> GetWorkshops()
{
    return db.Workshops
        .Include(w => w.Clients);
}

Note: You may need to add using System.Data.Entity; to use the lambda version of Include , otherwise you can use the string version.

I would recommend keeping your mappings in a separate mapping file, but if you are going to do it in the OnModelCreating method then this should do what you need.

    modelBuilder.Entity<Workshop>()  
        .HasRequired(c => c.Clients)  //or HasOptional depending on your setup
        .WithMany(d => d.Workshop) 
        .HasForeignKey(d => new { d.ID });

    modelBuilder.Entity<Clients>()  
        .HasRequired(c => c.Workshop)  //same
        .WithMany(d => d.Clients) 
        .HasForeignKey(d => new { d.ID });

Also in both entities add this to your ID properties:

[Key]
public int Id { get; set; }

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM