Question

I know that this is a repeated question and I know that this is not possible if there are additional properties in the "in the middle" table.

I had an idea how to get the effect of an m:N relationship instead of an 1:n-n-1, but I'd like to hear some other thoughts.

If I have three entities, A, B, and AB where AB makes the A:B relation possible and it has additional properties.

Using Databasefirst approach, I thought to make a partial class of A and B.

public partial Class A
{
    public IEnumerable<EntityObject> Bs 
    {
        get
        {
            return this.Select(p=>p.AB.B);
        }
        set { //... }
    }
}

Could something like this be possible.

Just doodling in my head. I am currently on vacation and have no computer, so this is not tested but just written on my cell phone.

I see that this could be a problem after context disposing or detaching, also with including in an eager loading approach.

Any thoughts?

Was it helpful?

Solution

If you are already treating AB as a distinct entity, then to get all B from A all you need is something like this:

public partial class A
{
    public IQueryable<B> Bs {
        get { return this.ABs.AsQueryable().Select(ab => ab.B).Distinct(); }
    }
}

I'm not sure how well this will perform, as compared to a built-in Many-To-Many supported by EF (without any payload), but it will give you what you are asking.

OTHER TIPS

If technically possible or not, expressing such a relationship with "additional properties in the in the middle table" as many-to-many relationship is just wrong because it hides that the "middle table" has a business meaning and therefore must be an entity on its own.

A somewhat classical example for such a model are RawMaterial and Product: A RawMaterial can be used in multiple Products and a Product can be made of multiple RawMaterials. The entity in between - maybe called RecipePart - contains a Quantity how many pieces of a given RawMaterial are used in a given Product.

If you have for example the product ChocolateBar and work with its relation to raw materials you will deal with a recipe that says a ChocolateBar has 60 units of Chocolate and 40 units of Milk, i.e. ChocolateBar has a collection of RecipeParts and every RecipePart describes the quantity and refers to the related RawMaterial. A ChocolateBar does not have a direct collection of RawMaterials in this business model.

For a particular query (maybe some statistics) you might be only interested in its raw materials - a chocolate bar is made if chocolate and milk, no matter how many units - but that is a special query in your business model and kind of an aggregation that ignores some pieces of the full detailed model information. This is what your helper property this.Select(p=>p.AB.B); does: It does not express the full relationship but is a specialized query that says: Give me only the RawMaterials for this Product, I don't want to know each quantity.

Characteristically you have left the property setter set { //... } a stub. When adding or changing entities it becomes obvious that the relationship cannot be many-to-many. It is not possible to assign only a list of RawMaterials to a Product. You must add the information how many units of each RawMaterial to get a valid Product model which means that Product must be related to the "middle entity" RecipePart.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top