5

Using Entity Framework 4 I want to create a base interface for my objects so that the properties of the base interface get implemented as fields in the table for each derived class (not in its own table), and then deal with the derived classes using the interface.

For example, have an interface and some classes like so:

public interface IBaseEntity
{
    public DateTime CreatedOn { get; set; }
    public string CreatedBy { get; set; }
}

public class SomeEntity : IBaseEntity
{
    public int SomeEntityId { get; }
    public string Name { get; set; }
    public DateTime CreatedOn { get; set; }
    public string CreatedBy { get; set; }
}

public class OtherEntity : IBaseEntity
{
    public int OtherEntityId { get; }
    public float Amount { get; set; }
    public DateTime CreatedOn { get; set; }
    public string CreatedBy { get; set; }
}

This would result in two tables in the database, SomeEntity and OtherEntity, which would have four fields each. SomeEntity has SomeEntityId, Name, CreatedOn and CreatedBy and OtherEntity has OtherEntityId, Amount, CreatedOn and CreatedBy. There is no IBaseEntity table.

I would expect to see this displayed in the designer as IBaseEntity being an abstract entity with the CreatedOn and CreatedBy properties and the two concrete entities having just their non-derived properties - so SomeEntity just has SomeEntityId and Name. There is an inheritance relationship between the concrete entities and the abstract entity.

Then I would like to have automatic column updates for these objects when saving them, like so:

namespace MyModel
{

    public partial class MyEntities
    {
        partial void OnContextCreated()
        {
            this.SavingChanges += new EventHandler(OnSavingChanges);
        }

        private static void OnSavingChanges(object sender, EventArgs e)
        {
            var stateManager = ((MyEntities)sender).ObjectStateManager;
            var insertedEntities = stateManager.GetObjectStateEntries(EntityState.Added);

            foreach (ObjectStateEntry stateEntryEntity in insertedEntities)
            {
                if (stateEntryEntity.Entity is IBaseEntity)
                {
                    IBaseEntity ent = (IBaseEntity)stateEntryEntity.Entity;
                    ent.CreatedBy = HttpContext.Current.User.Identity.Name;
                    ent.CreatedOn = DateTime.Now;
                }
            }
        }
    }
}

I am just starting out with Entity Framework and it seems like this should be able to be done fairly easily but how to actually implement it is escaping me. Am I way off track here or is this sort of thing possible in Entity Framework 4? The Table Per Concrete Type Strategy seems like the solution but I haven't been able to get it working.

1

2 Answers 2

3

The interface won't be part of your entity model and can't be displayed in the designer. But you can add it via a partial class, and then your code will work. We actually use a T4 template for this, but it works fine when done manually, too.

Sign up to request clarification or add additional context in comments.

1 Comment

Wow, deja vu from the old Delphi days! Maybe I'm asking the wrong question and an interface isn't the way to do it. What I would like is a way to have inheritance such that my tables understand that they have to implement the fields from the parent. So intially they have CreatedBy and CreatedOn but I could add other fields to the parent, say ModifiedBy and ModifiedOn, and all the descendent tables would now know to also implement those fields. Being able to work with the all the classes via the interface is certainly also beneficial but initially I'd like some sort of table template.
1

Well, this is pretty darned old but I thought I'd mention that you can accomplish what the original poster wants through abstract classes as well as the way the accepted answerer suggested.

2 Comments

This is true, but of limited use due to C# not supporting multiple-inheritance of classes. In this case the OP is creating an interface for Audit data which is unlikely to be something you want every class in the hierarchy to support.
you can't have "multiple-inheritance" where you inherit from more than one class all at once, but you can certainly have multiple levels of inheritance and accomplish what the OP wants that way. There are times to go with the way the accepted answer suggested (I do that sometimes) and there are times to use abstract classes. Just two different tools in the toolbox :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.