Inheritance problem

7 posts, 0 answers
  1. fabrice
    fabrice avatar
    3 posts
    Member since:
    Mar 2011

    Posted 07 Jan 2013 Link to this post

    Hi,

    I have created a new fluent project.

    I have a base class :

    [DataContract]
     public abstract class ModelMetadataBase : IModelBase
     {
            [DataMember]       
            public int Id
            {
                get { return _id; }
                set { _id = value; }
            }
            protected int _id;       
    }

    I have 2 classes that inherit from base class :

    [KnownType(typeof(ModelMetadataBase))]
    [KnownType(typeof(IList<MetaEnumItem>))]
    [DataContract]
    public class MetaEnum : ModelMetadataBase
    {
            [DataMember]
            public string Name
            {
                get { return _name; }
                set { _name = value; }
            }
            private string _name;
     
            [DataMember]
            public IList<MetaEnumItem> MetaEnumItemList
            {
                get { return _metaEnumItemList; }
                set { _metaEnumItemList = new List<MetaEnumItem>(value); }
            }
            private IList<MetaEnumItem> _metaEnumItemList = new List<MetaEnumItem>();
    }
     
    [KnownType(typeof(ModelMetadataBase))]
    [KnownType(typeof(MetaEnum))]
    [DataContract]
    public class MetaEnumItem : ModelMetadataBase
    {
            [DataMember]
            public int MetaEnumId
            {
                get { return _metaEnumId; }
                set { _metaEnumId = value; }
            }
            private int _metaEnumId;
     
            [DataMember]
            public int Value
            {
                get { return _value; }
                set { _value = value; }
            }
            private int _value;
    }

    In mapping code :

    public MappingConfiguration<MetaEnum> GetMetaEnumMappingConfiguration()
    {
                MappingConfiguration<MetaEnum> configuration = GetMetaEnumClassConfiguration();
                PrepareMetaEnumPropertyConfigurations(configuration);
                PrepareMetaEnumAssociationConfigurations(configuration);
                return configuration;
    }
     
    public MappingConfiguration<MetaEnum> GetMetaEnumClassConfiguration()
    {
                var configuration = new MappingConfiguration<MetaEnum>();
                configuration.MapType().Inheritance(InheritanceStrategy.Vertical).ToTable(SchemaMetadata + ".MetaEnum");
     
                return configuration;
    }
     
    public void PrepareMetaEnumPropertyConfigurations(MappingConfiguration<MetaEnum> configuration)
    {
                configuration.HasProperty(x => x.Id).IsIdentity(KeyGenerator.Autoinc).HasFieldName("ModelMetadataBase._id").ToColumn("Id").IsNotNullable().HasColumnType("int");
                configuration.HasProperty(x => x.Name).ToColumn("Name").HasColumnType("varchar").IsNotNullable().HasLength(50);
    }
     
    public void PrepareMetaEnumAssociationConfigurations(MappingConfiguration<MetaEnum> configuration)
    {
                configuration.HasAssociation(m => m.MetaEnumItemList).HasConstraint().ToColumn("MetaEnumId").IsDependent();
    }
     
    public MappingConfiguration<MetaEnumItem> GetMetaEnumItemMappingConfiguration()
    {
                MappingConfiguration<MetaEnumItem> configuration = GetMetaEnumItemClassConfiguration();
                PrepareMetaEnumItemPropertyConfigurations(configuration);
                return configuration;
    }
     
    public MappingConfiguration<MetaEnumItem> GetMetaEnumItemClassConfiguration()
    {
                var configuration = new MappingConfiguration<MetaEnumItem>();
                configuration.MapType().Inheritance(InheritanceStrategy.Default).ToTable(SchemaMetadata + ".MetaEnumItem");
                return configuration;
    }
     
    public void PrepareMetaEnumItemPropertyConfigurations(MappingConfiguration<MetaEnumItem> configuration)
    {
                configuration.HasProperty(x => x.Id).IsIdentity(KeyGenerator.Autoinc).HasFieldName("ModelMetadataBase._id").ToColumn("Id").IsNotNullable().HasColumnType("int");
                configuration.HasProperty(x => x.MetaEnumId).ToColumn("MetaEnumId").IsNotNullable().HasColumnType("int");
                configuration.HasProperty(x => x.Value).ToColumn("Value").IsNotNullable().HasColumnType("int");
    }

    1) Why in the method : PrepareMetaEnumAssociationConfigurations
    configuration.HasAssociation(m => m.MetaEnumItemList).HasConstraint().ToColumn("MetaEnumId").IsDependent();
    I cant't write :
    configuration.HasAssociation(m => m.MetaEnumItemList).HasConstraint((x,y)=>x.Id == y.MetaEnumId) .ToColumn("MetaEnumId").IsDependent();

    ==> Error 5 A property from the configured type does not take part in the expression.

    2) I create a new odata service v2 :

    [System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
        public partial class DataContextService : OpenAccessDataService<APlus.Framework.DAL.DataContext>
        {
            /// <summary>
            /// Initializes the service.
            /// </summary>
            /// <param name="config">The configuration object.</param>
            public static void InitializeService(DataServiceConfiguration config)
            {           
                config.SetEntitySetAccessRule("*", EntitySetRights.All);
     
                // TODO: Set service behavior configuration options
                // Examples:
                // config.DataServiceBehavior.AcceptCountRequests = true;
                // config.DataServiceBehavior.AcceptProjectionRequests = true;
                config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
            }
        }

    When i execute the service ==> The entity type 'MetaEnumItem' does not have any key properties. Please make sure the key properties are defined for this entity type.

    Kind regards
  2. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 10 Jan 2013 Link to this post

    Hello Fabrice,

    Unfortunately this is a known issue in our data services metadata provider - inheritance is not supported at the moment. We will have to fix the problems there and test the whole inheritance scenario more thoroughly. We will try to do that for the upcoming Q1 2013 release.
    Please excuse us for the inconvenience caused.

    All the best,
    Alexander
    the Telerik team
    Q3'12 SP1 of OpenAccess ORM packs Multi-Table Entities mapping support. Check it out.
  3. DevCraft banner
  4. Trevor
    Trevor avatar
    7 posts
    Member since:
    Jul 2012

    Posted 25 Sep 2013 Link to this post

    Was this addressed in the Q1 2013 release?
  5. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 30 Sep 2013 Link to this post

    Hello Trevor,

    Yes, there have been some improvements in this area. Inheritance is supported, although there are a few limitations - horizontally mapped base classes cannot be exposed by the service and only one IQueryable endpoint per hierarchy is allowed.

    Can you please share more details about the scenario you are trying to implement? This way we will be able to provide you with more concrete information.

    Regards,
    Alexander
    Telerik
    OpenAccess ORM Q3 2013 Beta is available for immediate download in your account. Get it now and play with the latest bits. See what's new >>
  6. Trevor
    Trevor avatar
    7 posts
    Member since:
    Jul 2012

    Posted 07 Oct 2013 Link to this post

    We also have a fluent model.  We have a base class, for example, Business.  This is inherited by Employee, Customer, Vendor, etc.

    Business has fields like Number, Address, Phone, etc. that are used in the inherited classes.  If I disable the inheritance, and manually replicate those fields in each class, I'm able to create my webservice.  Otherwise, with the inheritance intact, I just get an error when I try to build and run the webservice:  An error occurred while trying to write an error payload.

    I believe we are using Horizontal inheritance - storing all of the inherited fields in each table in the database.

    Also, does only one IQueryable endpoint per hierarchy mean that we would only be able to expose "Employee" or "Customer" but not both since they are in the same hierarchy?

    Either way, it doesn't seem like this will work for our Fluent Model based on the current limitations.

  7. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 09 Oct 2013 Link to this post

    Hi Trevor,

    It would be a problem if Employee derives from Customer or vice versa, but if they only have a common base class it should be fine.
    If this is your case but you continue getting errors, please feel free to send us a support ticket and attach your project there, so we can debug it and narrow down the problem.

    Regards,
    Alexander
    Telerik
    OpenAccess ORM Q3 2013 Beta is available for immediate download in your account. Get it now and play with the latest bits. See what's new >>
  8. Trevor
    Trevor avatar
    7 posts
    Member since:
    Jul 2012

    Posted 09 Oct 2013 Link to this post

    They do only have a common base class.

    I submitted a sample project with support ticket: 744684.

    Thanks!
    Trevor
Back to Top
DevCraft banner