none
Inherit from abstract class RRS feed

  • Question

  • Hi all,


    I'm trying to change my L2S design to L2E. Currently I have a simple class, such as the following:

        [Table(Name="titles")]
        public sealed class Title : BaseDataObject
        {
            #region Local variables
    
            private string description;
    
            #endregion
    
            #region Initialization
    
            protected override void Initialize()
            {
                //Get rights
                this.Rights = new UserRights(true, true, true, true);
            }
    
            public Title()
            {
                Initialize();
            }
    
            #endregion
    
            #region Properties
    
            //Public
            [Column(IsPrimaryKey = true, Name = Const.Columns.IdNo, Storage = Const.Fields.Id, DbType = Const.DBTypes.IntNotNull, IsDbGenerated = true)]
            public int ID
            {
                get { return this.id; }
                private set { this.id = value; }
            }
    
            [Column(Name = @"title", Storage = Const.Fields.Description)]
            public string Description
            {
                get { return this.description; }
                set { this.description = value; }
            }
    
            //Private
            [Column(Name = Const.Columns.IdNoPrimarygroup, Storage = Const.Fields.PrimarygroupId)]
            private int PrimarygroupID
            {
                get { return this.primarygroupID; }
                set { this.primarygroupID = value; }
            }
    
            #endregion
    
            #region Methods
    
            public static Title Load(int ID)
            {
                //Load object by ID
                var obj = CurrentUser.Database.Titles.First(o => o.ID == ID);
    
                //Return object
                return obj;
            }
    
            protected override ErrorsEnum Validate()
            {
                ErrorsEnum err = ErrorsEnum.Success;
    
                //Validation
                try
                {
                    if (this.Description.Trim().Length == 0)
                        err = ErrorsEnum.NoDescription;
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine(e);
                    err = ErrorsEnum.ValidateFailed;
                }
    
                return err;
            }
    
            protected override void _Save()
            {
                //Set primarygroup before saving
                this.PrimarygroupID = CurrentUser.PrimarygroupID;
    
                //Add new record
                if (this.ID == 0)
                    CurrentUser.Database.Titles.InsertOnSubmit(this);
            }
    
            protected override void _Delete()
            {
                CurrentUser.Database.Titles.DeleteOnSubmit(this);
            }
    
            #endregion
        }


    The base object is as follows:

        public abstract class BaseDataObject
        {
            #region User rights
            #endregion
    
            #region Local variables
    
            protected int id;
            protected int primarygroupID;
    
            #endregion
    
            #region Initiailization
    
            public BaseDataObject()
            {
            }
    
            protected abstract void Initialize();
    
            #endregion
    
            #region Methods
    
            protected virtual ErrorsEnum Validate()
            {
                return ErrorsEnum.Success;
            }
    
            public virtual ErrorsEnum Save()
            {
                //Success
                ErrorsEnum err = ErrorsEnum.Success;
    
                //Rights to add/edit
                if (!Rights.CanAdd)
                    err = ErrorsEnum.AddNotAllowed;
                else if (!Rights.CanEdit)
                    err = ErrorsEnum.EditNotAllowed;
    
                //Validation
                if (err == ErrorsEnum.Success)
                    err = Validate();
    
                //If success proceed
                if (err == ErrorsEnum.Success)
                {
                    try
                    {
                        //Call inherited class save
                        _Save();
    
                        //Submit changes to db
                        CurrentUser.Database.SubmitChanges();
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Debug.WriteLine(e);
                        err = ErrorsEnum.InsertFailed;
                    }
                }
    
                //Return success / failure
                return err;
            }
    
            protected virtual void _Save()
            {
            }
    
            public virtual ErrorsEnum Delete()
            {
                //Success
                ErrorsEnum err = ErrorsEnum.Success;
    
                //Right to delete
                if (!Rights.CanDelete)
                    err = ErrorsEnum.DeleteNotAllowed;
    
                //If success proceed
                if (err == ErrorsEnum.Success)
                {
                    try
                    {
                        //Delete and submit changes to the db
                        if (this.id > 0)
                        {
                            //Call inherited class delete
                            _Delete();
    
                            //Update db
                            CurrentUser.Database.SubmitChanges();
                        }
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Debug.WriteLine(e);
                        err = ErrorsEnum.DeleteFailed;
                    }
                }
    
                //Return success / failure
                return err;
            }
    
            protected virtual void _Delete()
            {
            }
    
            #endregion
        }

    As you can see from the above classes, the Save & Delete methods in the base class do most of the work, whilst calling the _Save & _Delete methods of the inherited class where validation is performed and other stuff.

    Now, using L2E and the edmx file, I cannot use this same design because my entity classes inherit from EntityObject.

    Is there an alternative that lets me keep this design?

    Thanks,

    Ivan






    • Edited by Cryo75 Monday, May 7, 2012 1:12 PM
    Monday, May 7, 2012 1:12 PM

Answers

  • I'm generating my POCO classes using EF4 so the generated classes do not inherit from EntityObject. This allows me to inherit my partial classes from BaseDataObject and currently this is the best solution for me.

    However, if in the future I need to generate my classes from different templates (eg for self-tracking) and the generated classes inherit from EntityObject or any other EF class, I was thinking that I could modify the .tt so that the generated partial class would also inherit from my own BaseDataObject.

    This should work, right?

    Thursday, May 10, 2012 7:00 AM

All replies

  • Hi Cryo75,

    Welcome to MSDN Forum.

    The eneities which Entity Framework auto-generated are partial class, so you can write another partial class to contains all the operations you need.

    Best Regards


    Allen Li [MSFT]
    MSDN Community Support | Feedback to us

    Tuesday, May 8, 2012 7:55 AM
    Moderator
  • That's correct, and I do need to write another partial class to include behavior eg. Load, Save, Delete. However the new partial class cannot inherit from my BaseDataObject, and each new partial class that I create will have lots of code... something that I would have solved with my abstract BaseDataObject class.

    Ivan

    Tuesday, May 8, 2012 7:57 AM
  • Hi Cryo75,

    You can use code-first instead of to realize TPC. Please refer to the link below. This article introduces how to use code first to realize inheritance. It's very similar with the scenario of yours. Writing an abstract class and write some child classes to derive from it. Each child class maps to one database table.

    Inheritance with EF Code First: Part 3 – Table per Concrete Type (TPC)

    Best Regards


    Allen Li [MSFT]
    MSDN Community Support | Feedback to us

    Tuesday, May 8, 2012 8:24 AM
    Moderator
  • Hi Cryo75,

    I am writing to check the status of the issue on your side. Would you mind letting us know the result of the suggestions?

    If you need further assistance, please feel free to let me know. I will be more than happy to be of assistance.

    Have a nice day.


    Allen Li [MSFT]
    MSDN Community Support | Feedback to us

    Thursday, May 10, 2012 2:38 AM
    Moderator
  • Hi Cryo75,

    I am writing to check the status of the issue on your side. Would you mind letting us know the result of the suggestions?

    If you need further assistance, please feel free to let me know. I will be more than happy to be of assistance.

    Have a nice day.


    Allen Li [MSFT]
    MSDN Community Support | Feedback to us

    Thursday, May 10, 2012 2:40 AM
    Moderator
  • I'm generating my POCO classes using EF4 so the generated classes do not inherit from EntityObject. This allows me to inherit my partial classes from BaseDataObject and currently this is the best solution for me.

    However, if in the future I need to generate my classes from different templates (eg for self-tracking) and the generated classes inherit from EntityObject or any other EF class, I was thinking that I could modify the .tt so that the generated partial class would also inherit from my own BaseDataObject.

    This should work, right?

    Thursday, May 10, 2012 7:00 AM
  • Hi Cryo75,

    Yes, to modify .tt file is the common way to configure the entities in Entity Framework.

    Best Regards


    Allen Li [MSFT]
    MSDN Community Support | Feedback to us

    Thursday, May 10, 2012 7:08 AM
    Moderator