0

I have a set of fields that I intend to share between multiple models. I want all the fields to be included in each entity's table (not just one table for the fields). I'm more familiar with languages such as Python, where this type of pattern is called a "mixin", essentially a class that doesn't exist on its own (it doesn't get instantiated/doesn't have a table in the case of a model class). Instead, the derived class simply inherits the fields and its table looks as if the fields were simply included right on the model class.

The concept of a "Complex Type" in Entity Framework seems like a close proxy to what I'm looking for, but the inability to include navigation properties is a bit of killer. Is there any other way to do this, or if Complex Types are the answer, then what should I do about the navigation properties?

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444

3 Answers3

1

I've read this note in a book:

An interesting possibility beyond base classes and interfaces are mixins, but they are an OOP feature not supported by .NET languages. A mixin is a class that provides a certain functionality that other classes can inherit, but it is not meant to be a standalone class. Put another way, a mixin is like an interface where some of the members might contain a predefined implementation. Mixins are supported in some dynamic languages, including Python and Ruby. No .NET languages currently support mixins, but mixins can be simulated using ad hoc frameworks such as Castle. DynamicProxy. With this framework, you first define a class that contains all the methods you want to inject in an existing class—the mixin. Next, you use the framework to create a proxy for a given class that contains the injected methods. Castle.DynamicProxy uses Reflection.Emit internally to do the trick.

Yasser Sinjab
  • 578
  • 6
  • 19
  • Sorry, but TPT is pretty much exactly what I didn't want. I don't want the "mixin" to have it's own table. Basically, I'm just looking for a way to add a set of common fields to the other models without having to literally copy-and-paste the set to every model. They would inherit the fields from the base (and of coure abstract) class, but they would treat it as if the fields had literally been defined directly on the derived classes. The main issue involves doing this in a way that Entity Framework can understand. – Chris Pratt Oct 17 '12 at 14:16
  • OK , you can read about mixins in c# in this link:http://stackoverflow.com/questions/255553/is-it-possible-to-implement-mixins-in-c and i'll edit my answer as soon as i get more information about it :) – Yasser Sinjab Oct 17 '12 at 14:49
1

You can do this using inheritance. If you've already considered that, I apologize. Code follows.

public abstract class WidgetBase 
{
    public string Name { get; set; }
}

public class SweetWidget : WidgetBase 
{
    public int SweetnessFactor { get; set; }
}

public class SourWidget : WidgetBase
{
    public int Sourness { get; set; }
}

Then in your model configuration, you do:

const string discriminator = "WidgetType";
Map<SweetWidget>(mc => mc.Requires(discriminator).HasValue("Sweet"));
Map<SourWidget>(mc => mc.Requires(discriminator).HasValue("Sour"));

You will need to add a column, "WidgetType", to your table. EF will then populate it as specified in the mapping.

Note that the base class MUST be abstract. As long as your table contains all of the fields for all of the derived classes, this is how you do Table Per Hierarchy in EF Code First.

ItsJason
  • 747
  • 1
  • 4
  • 20
  • Yeah, sorry, apparently, I'm being very difficult with this question. I'm actually already implementing TPH elsewhere. What I'm looking for here is basically just DRY. As far as the application and database are concerned, there would just be Sweet and Sour, in your example. They would each have a "Name" field, but that's it. "WidgetBase" would exist for no other purpose than adding the "Name" field. It would not have a table, and I would never use it anywhere else in the code other than having Sweet and Sour inherit from it. – Chris Pratt Oct 18 '12 at 19:35
  • For what it's worth. What I'm looking for is closer to TPC (Table-Per-Concrete Type), though that requires way too much wireup code to actually be worth it in the long run, or Entity Framework's ComplexType. The problem is that with either approach, I can't include navigation properties. Perhaps, it's just not possible, but I find it hard to believe that any modern MVC framework wouldn't account of a mixin/abstract form of inheritance simply for the purposes of DRY. – Chris Pratt Oct 18 '12 at 19:42
0

Actually had a chance to discuss this with one of the developers on Entity Framework. It's not technically possible at this time. It's apparently being kicked around, but no one is working on it at this point. Complex Types are a sort-of version, but they of course don't support navigation properties. Thanks to everyone who took at stab at it for me.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444