Self-referencing many-to-many relationship EF code

2019-05-07 20:20发布

问题:

I work with ASP.NET MVC With Durandal/Breeze templates.

Let's say I have the following class:

public class Person
{
    public int Id { get; set; }
    public string Firstname { get; set; }    
    public string Lastname { get; set; }
    public virtual List<Person> Friends { get; set; }
}

With the following EF Fluent API:

modelBuilder.Entity<Person>()
            .HasMany(m => m.Friends)
            .WithMany()
            .Map(m => m.ToTable("Friends"));

The database is generated successfully.

The problem is when I perform a que


ry with Breeze (client side) I have no data for the Friends property.

    var query = entityQuery.from('Person')
        .where('id', '==', 123)
        .expand("Friends");

When the query is executed I get as result the requested People entity with all the data except the Friends property is always an empty array. When I check the Json answer I see that also the data are transmitted. Even data for the Friends property. However they are not linked to the Friends property itself.

My question: what do I have to do to have my Friends property filled with values?

Thanks.

回答1:

You must declare a foreign key in Person. Breeze requires the FK to correctly resolve associations.

Edit:

I just realized you are asking about a many-to-many relationship. (yeah, I should have read the post title...) Breeze does not support many-to-many associations. However, you could have two one-to-many relationships to work as a many-to-many. (i.e. many-to-one-to-many) In this case, you will need to define the linking table/entity and the foreign key as mentioned earlier. (see http://www.breezejs.com/documentation/navigation-properties)



回答2:

Try this answer: *Note that this is incomplete because i do not see the other table that you are trying to m-2-m with Persons. ( You will only want to use Persons Table and the 2nd Table , NOT table=Friends.

 db.Person
          .Include(c => c.Friends)
          .Where(c => c.Friends.Any(up => up.FriendVlaue == c.FirstName)) //c.from Persons
          .Select(c => new
          {
              PersonID = c.ID,
              PersonName = c.FirstName,
              PersonCount = c.Person.Count()
          })

         {

From This answer



回答3:

You should include Friends in the results. You can do this by adding Include("Friends")at Server Side API.

[HttpGet]
public IQueryable<Person> Persons()
{
   return _contextProvider.Persons.Include("Friends");
}

If you don't want to return always the Friendsreference, you can create another method in the API such as PersonsWithFriends as suggested in here (Specialized query actions).