Partager via


MEST - What is it and how does it work?

MEST stands for Multiple EntitySets per Type.

It is one of the features of the Entity Framework that is typically missing from ORM stacks.

The idea is that you can store the same EntityType in multiple EntitySets. For the purposes of this discussion you can think of EntitySets as analogous to Tables.

Now MEST works very well for very simple Entities that have no associations. For example you can easily take something like this:

MestNoAssociationsSingleSet

And add a second EntitySet:

MestNoAssociationsMultipleSets

Which of course in ObjectServices means you can do things like this:

var good = from c in ctx.GoodCustomers
select c;

var bad = from c in ctx.BadCustomers
select c;

MEST is also why you see the name of the Set in the convenient AddToSet(...) methods on the ObjectContext, you get to choose the EntitySet that the new Entity should live in by name.

i.e.

Customer good = CreateGoodCustomer();
ctx.AddToGoodCustomers(good)

Customer bad = CreateBadCustomer();
ctx.AddToBadCustomers(bad);

Seems pretty straight forward doesn't it.

Unfortunately in V1 of the Entity Framework there are definitely some gotchas when your Entities have Associations too.

For example imagine you have this model:

MestBasicModel

What we have here is the 4 EntityTypes and 3 AssociationTypes. As you can see (or at least you could if I had taken the time to put cardinality into the picture) a Customer has Orders which have OrderLines each of which are for a particular product.

Now of course to use this in the Entity Framework you need to create 4 EntitySets (Green Boxes) and 3 AssociationSets (Green Arrows) too:

MestBasicModelWithSets

 

No problem. That works great.

However if you try to add a second EntitySet for Customers now, things start to get a little tricky:

MestBasicModelWithMestTheProblem

The problem is that you can't create 2 AssociationSets of the same type (in this case CustomerOrders) that point to the same EntitySet on one end (i.e. Orders).

So I can't link both GoodCustomers and BadCustomers to Orders.

Why? Well the problem is that Associations are always bi-directional, unlike foreign keys, so you need to be able to navigate an Association in both directions.

Which in the above model you can't. See if you go from an Order to a Customer via the CustomerOrders association the target set, either GoodCustomers or BadCustomers, can't be determined, it is ambiguous.

The EntityFramework in V1 just can't handle this ambiguity.

Going forward we are trying to work out how to handle this situation gracefully.

Still today the only workaround is to duplicate the whole graph.

I.e. in this case we started with 4 EntitySets & 3 AssociationSets, and to make one of those EntitySets MEST, I need to clone everything, so I end up with 8 EntitySets & 6 AssociationSets:

MestComplexModel

Without doubt this occasionally makes sense, for example if the Orders, OrderLines and Products for a BadCustomer are stored in a logically different place to those for GoodCustomers.

Unfortunately often that is not the case, i.e. you don't really have two tables of Products, I have just one.

So to use MEST in these situations you end up having to lie to the EntityFramework, by creating fake tables* in the SSDL using a view (DefiningQuery) and Insert, Update and Delete Functions.

Not exactly ideal.

The moral of the story, I think, is that MEST can be useful, particularly if you have no associations or you already have two logically distinct graphs.

Otherwise MEST can be quite tricky.

Hopefully now you understand MEST a little better, and can see it for what it is, just another tool in your modeling arsenal.

Use as appropriate.

*See my post on Associations with Payloads for some tips here if you need to do this.

Comments

  • Anonymous
    June 27, 2008
    If you've been paying attention to what the Entity Framework team has been saying. You will remember
  • Anonymous
    June 27, 2008
    Hi,You provided a weak example. GoodCustomer and BadCustomer are disjoint subsets of Customer. So for a given Customer it is ALWAYS possible to determine to which set it belongs.There are limitations according to the mapping chosen. With TPH and TPT (table per type (or vertical partitioning)) ALL subclasses are disjoint (there is only one PK). But with TPC (table per concrete type or horizontal partitioning)) the subclasses are NOT required to be disjoint.Martin
  • Anonymous
    June 30, 2008
    Hi Alex,You provided a weak example. The customer entity decomposes DISJOINT into GoodCustomer and BadCustomer. So for a given order, the subtype of customer is always determinable.Depending on the inheritance mapping, there are different possibilities. For TPH and TPT (vertical) the supertype always decomposes disjoint. For TPC (horizontal) the subtypes are not required to form disjoint sets.But the point is not the mapping. It's the definition of the entity set (conceptually!). If we allow multiple inheritance, then TPH and TPT are just inadequate mappings. So, the disjointnes of the subtypes is a conceptual fact.I'd like to see EF handle that correctly in future versions (V2?)Martin
  • Anonymous
    March 24, 2009
    Background If you've been reading the EF Design Blog you will have seen that we recently announced something
  • Anonymous
    April 15, 2009
    The Problem: In some of earlier tips we talked about using Attach to load things into the ObjectContext
  • Anonymous
    May 01, 2009
    Background: In order to be an EF power user today you really need to be familiar with EntitySets . For
  • Anonymous
    June 19, 2009
    Background: In order to be an EF power user today you really need to be familiar with EntitySets. For
  • Anonymous
    June 19, 2009
    The Problem: In some of earlier tips we talked about using Attach to load things into the ObjectContext
  • Anonymous
    June 21, 2009
    Background If you've been reading the EF Design Blog you will have seen that we recently announced