This question is locked. New answers and comments are not allowed.
Joseph Lam
Top achievements
Rank 1
Joseph Lam
asked on 21 Jul 2014, 10:48 PM
My model looks like this:
public abstract class EntityBase
{
public int ID { get; set; } // intended to be the identity for each concrete class
}
public class MyEntity: EntityBase
{
public string SomeField { get; set; }
}
My mapping code:
var entityBaseMapping = new MappingConfiguration<EntityBase>();
entityBaseMapping.MapType().Inheritance(InheritanceStrategy.Horizontal);
var myEntityMapping = new MappingConfiguration<MyEntity>();
myEntityMapping.MapType();
myEntityMapping.HasProperty(x => x.ID).IsIdentity();
Get this error when compiling:
Error 1 Type 'MyEntity' cannot access private identity field '<ID>k__BackingField' declared by type 'EntityBase'. The declaring type enhances this field as non-identity field. Make sure to use a consistent mapping for both types or declare the field as protected. Alternatively consider moving the identity field to the derived class. (OpenAccessEnhancedCopyKeyFieldsFromObjectId)
public abstract class EntityBase
{
public int ID { get; set; } // intended to be the identity for each concrete class
}
public class MyEntity: EntityBase
{
public string SomeField { get; set; }
}
My mapping code:
var entityBaseMapping = new MappingConfiguration<EntityBase>();
entityBaseMapping.MapType().Inheritance(InheritanceStrategy.Horizontal);
var myEntityMapping = new MappingConfiguration<MyEntity>();
myEntityMapping.MapType();
myEntityMapping.HasProperty(x => x.ID).IsIdentity();
Get this error when compiling:
Error 1 Type 'MyEntity' cannot access private identity field '<ID>k__BackingField' declared by type 'EntityBase'. The declaring type enhances this field as non-identity field. Make sure to use a consistent mapping for both types or declare the field as protected. Alternatively consider moving the identity field to the derived class. (OpenAccessEnhancedCopyKeyFieldsFromObjectId)
5 Answers, 1 is accepted
0
Hi Joseph,
The reason is that the Telerik Data Access Enhancer tool is trying to access the filed of the ID property when processing the derived class. As the auto property generates a private filed it is not accessible from the derived class context. To solve this issue use a full property where the backing field is protected, like this:
I hope this helps. Should you have any additional questions do not hesitate to get back.
Regards,
Kaloyan Nikolov
Telerik
The reason is that the Telerik Data Access Enhancer tool is trying to access the filed of the ID property when processing the derived class. As the auto property generates a private filed it is not accessible from the derived class context. To solve this issue use a full property where the backing field is protected, like this:
public
abstract
class
EntityBase
{
protected
int
iD;
public
int
ID
{
get
{
return
this
.iD;
}
set
{
this
.iD = value;
}
}
// intended to be the identity for each concrete class
}
I hope this helps. Should you have any additional questions do not hesitate to get back.
Regards,
Kaloyan Nikolov
Telerik
OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
0
Joseph Lam
Top achievements
Rank 1
answered on 24 Jul 2014, 01:27 PM
Thanks. I think the example in the documentation missed this point:
http://docs.telerik.com/data-access/developers-guide/code-only-mapping/inheritance/fluent-mapping-inheritance-default-mapping
In the C# Animal class it should have used a protected backing field.
http://docs.telerik.com/data-access/developers-guide/code-only-mapping/inheritance/fluent-mapping-inheritance-default-mapping
In the C# Animal class it should have used a protected backing field.
0
Joseph Lam
Top achievements
Rank 1
answered on 25 Jul 2014, 02:07 PM
Is there a way to configure the identity column once for the abstract base class so I don't have to repeat "myEntityMapping.HasProperty(x => x.ID).IsIdentity();" for all my entities?
0
Hi Joseph,
Kindly find the answers you inquiries as follows:
1. Configuring the identity property in Horizontal inheritance
The general idea behind the horizontal inheritance structures is that the base class does not have a representation inside the database. With this in mind, and in order for the proper runtime behavior of Telerik Data Access, it is important that each of the child classes has its own configuration for the identity property regardless of the fact that in the conceptual model, it belongs to the base class.
2. Usage of protected backing fields in the documentation examples
Indeed, the example demonstrated in the mentioned article does not provide you with the implementation of the Animal class. I added a task for an update of the documentation with the relevant information, but at the time present I cannot provide you with a timeframe for it.
I hope this helps. If you need further information, do not hesitate to get back to us.
Regards,
Doroteya
Telerik
Kindly find the answers you inquiries as follows:
1. Configuring the identity property in Horizontal inheritance
The general idea behind the horizontal inheritance structures is that the base class does not have a representation inside the database. With this in mind, and in order for the proper runtime behavior of Telerik Data Access, it is important that each of the child classes has its own configuration for the identity property regardless of the fact that in the conceptual model, it belongs to the base class.
2. Usage of protected backing fields in the documentation examples
Indeed, the example demonstrated in the mentioned article does not provide you with the implementation of the Animal class. I added a task for an update of the documentation with the relevant information, but at the time present I cannot provide you with a timeframe for it.
I hope this helps. If you need further information, do not hesitate to get back to us.
Regards,
Doroteya
Telerik
OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
0
Andrey
Top achievements
Rank 2
answered on 19 Jan 2016, 02:44 PM
This can be achieved without the use of inheritance
public
partial
class
ModelMetadata : FluentMetadataSource
{
protected
override
IList<MappingConfiguration> PrepareMapping()
{
List<MappingConfiguration> mappingConfigurations =
new
List<MappingConfiguration>();
mappingConfigurations.Add(CreateBaseConfiguration<Positions>());
mappingConfigurations.Add(CreateBaseConfiguration<Departament>());
return
mappingConfigurations;
}
}
private
MappingConfiguration<T> CreateBaseConfiguration<T>() where T : IPortalDataBase
{
MappingConfiguration<T> baseConfig =
new
MappingConfiguration<T>();
baseConfig.MapType().WithConcurencyControl(OptimisticConcurrencyControlStrategy.Version).UseDefaultMap();
baseConfig.HasProperty(c => c.Id).IsIdentity(KeyGenerator.Guid).IsNotNullable();
baseConfig.HasProperty(c => c.Timestamp).IsVersion();
baseConfig.HasProperty(c => c.Create).IsCalculatedOn(DateTimeAutosetMode.Insert);
baseConfig.HasProperty(c => c.Update).IsCalculatedOn(DateTimeAutosetMode.InsertAndUpdate);
baseConfig.HasProperty(c => c.Status).HasDefaultValue();
return
baseConfig;
}
use interface
public
interface
IPortalDataBase
{
Guid Id {
get
;
set
; }
DateTime Create {
get
;
set
; }
DateTime Update {
get
;
set
; }
Int64 Timestamp {
get
;
set
; }
DataStatus Status {
get
;
set
; }
}
The main drawback - the interface implementation. But it can just copy (or use the T4). But changing the interface implementation (a rare problem) and the class CreateBaseConfiguration we get a list of errors implementation of the interface in the other classes. Which just decide copying.
public
class
Departament : IPortalDataBase
{
public
Guid Id {
get
;
set
; }
public
DateTime Create {
get
;
set
; }
public
DateTime Update {
get
;
set
; }
public
Int64 Timestamp {
get
;
set
; }
public
DataStatus Status {
get
;
set
; }
public
string
Name {
get
;
set
; }
}