Access hidden property through base class c# - c#

In my ASP.NET Core API, I have a DTO class BaseBDto and another DerivedBDto that inherits from it, and hides some of its properties, because they're required in DerivedBDto. The properties of BaseBDto and DerivedBDto are objects of another classes, BaseADto and DerivedADto respectively, that follow the same logic as the first ones. I also have a BaseModel class to which both BaseBDto and DerivedBDto will be mapped through another class Mapper.
Something like the following code:
using System.ComponentModel.DataAnnotations;
public class BaseADto
{
public string Name { get; set; }
}
public class DerivedADto : BaseADto
{
[Required]
public new string Name { get; set; }
}
public class BaseBDto
{
public BaseADto A { get; set; }
}
public class DerivedBDto : BaseBDto
{
[Required]
public new DerivedADto A { get; set; }
}
public class BaseModel
{
public string NameModel { get; set; }
}
public static class Mapper
{
public static BaseModel MapToModel(BaseBDto dto) => new BaseModel
{
NameModel = dto.A.Name
};
}
But it turns out, when passing a DerivedBDto object to the MapToModel method, it's trying to access the values of the BaseBDto (which are null) instead of the DerivedBDto ones.
Is there any way I can achieve this behavior?
I can only think of declaring BaseBDto as abstract, but that would prevent me from instantiating it, which I need to do.
PS: I already asked a similar question here, but I oversimplified my code sample, so I felt another question was necessary.
Also, the solution provided there doesn't work because I can't override the A property at DerivedBDto with a DerivedADto since it must have the same type as the A property at BaseBDto.

Have you tried changing the MapToModel signature to be generic. The below
public static BaseModel MapToModel<T>(T dto) where T : BaseBDto => new BaseModel
{
NameModel = dto.A.Name
};

Related

How to suppress based-class property in favor of the same new derived-class property on model creating

I have a base class MyBaseClass, with a wrapper class MyWrapperClass which is derived from that base class. The purpose of declaring wrapper class is to detaching the EntityFramework-related annotations, Id properties and navigation properties from the base class. The structure of base class and derived class are as follows:
public class MyBaseClass
{
public ClassA MyProperty { get; set; }
}
public class MyWrapperClass: MyBaseClass
{
public int Id { get; set; }
public new ClassAWrapper MyProperty { get; set; }
}
I cannot use virtual...override pattern on MyProperty, because of the differet types for MyProperty in base class and derived class.
Thus, i put new keyword before MyProperty property, and i expect the EntityFramework to create the model based on ClassAWrapper instead of ClassA.
But i get an error when trying to add-migration: "ClassA should have a key". While ClassA has not a key property, but ClassAWrapper has.
DbContext implementation is as follows:
public class MyDbContext : DbContext
{
public DbSet<MyDerivedClass> MyDerivedClass { get; set; }
...
}
Problem: I need to tell the EntityFramework to give up on the MyProperty class of the base class (which is of type ClassA), and look at the same property in the derive class (with type ClassAWrapper) when creating the model.
Try NotMapped and Key data annotations, like this:
public class MyBaseClass
{
[NotMapped]
public ClassA MyProperty { get; set; }
}
public class MyWrapperClass: MyBaseClass
{
[Key]
public int Id { get; set; }
public new ClassAWrapper MyProperty { get; set; }
}

Problem in class design with multiple base model

I have a base class for all the ENTITIES of my project which is inheriting from below model :
public class BaseModel
{
public int Id { get; set; }
public int CreatedDate { get; set; }
public override string ToString();
}
Now I have 1 another functionality which is common for so many modules and I want to keep BaseModel for that functionality and want it to be inherited from it.
Public class BaseNotice
{
// Common info related to notice which is use to send notice to employees in different scenarios
}
Now our every model is suppose to inherit from BaseModel so inheriting from BaseNotice will be multiple inheritance.
Now I cannot like below :
Public class BaseNotice : BaseModel
{
// Common info related to notice which is use to send notice to employees in different scenarios
}
Because I would like to control functionality related to Notice from BaseNotice model and for notice I would like to keep BaseNotice as base model.
But I am not getting how to avoid multiple inheritance here and so what would be the proper way to design this?
There is No need to Multiple Inheritance. you can do that in this way:
public class BaseModel
{
public int Id { get; set; }
public int CreatedDate { get; set; }
public override string ToString();
}
public interface IBaseNotice
{
// Base Notices Contracts should be placed here
}
Public class BaseNotice: IBaseNotice
{
// Common info related to notice which is use to send notice to employees in different scenarios
}
public class ModelX:BaseModel
{
public IBaseNotice Notice { get ; set; }
public ModelX(IBaseNotice baseNotice)
{
Notice = baseNotice;
}
}
Or you can use Second Generation of your BaseModel:
public class BaseModeNoticable:BaseModel
{
public IBaseNotice Notice { get ; set; }
public BaseModeNoticable(IBaseNotice baseNotice)
{
Notice = baseNotice;
}
}

How to set up Entity Framework model to be derived from the custom class with already existing fields?

I am creating an application using Entity Framework 6.0 and Database-First approach. After I updated model from the database, I realised the essential need models to be derived from a BaseEntity class. The reason is that I need the base class to access the Id property using the BaseEntity class because the model class is often not specified.
My current solution is simple. According to Luke answer I implemented the partial class schema and directly derived a model class from RootEntity. In fact, the RootEntity class has the Id property as the model classes do. The compiler says CS0114 warning that classes should override properties. Since the model is autogenerated it cannot override properties.
What is the best practice to solve the particular issue? I'd like to implement a cleared architecture but this unpretty pattern may confuse anyone who reads my code.
// autogenerated EF code
public partial class Education
{
public int Id { get; set; }
public string Title { get; set; }
public System.DateTime AwardDate { get; set; }
public Nullable<int> PersonId { get; set; }
public virtual Person Person { get; set; }
}
// the base custom class I wont others to be derived from
public class RootEntity
{
public int Id { get; set; }
}
// partial class deriving
public partial class Education : RootEntity { }
EDIT:
The best solution I've found is to release the RootEntity class as an interface IPrimary. It also doesn't allow to directly create an object and provides a clearer definition of the required functionality.
public interface IPrimary
{
int Id { get; set; }
}
The best solution I've found is to release the RootEntity class as an interface IPrimary. It also doesn't allow to directly create an object and provides a clearer definition of the required functionality.
public interface IPrimary
{
int Id { get; set; }
}
public partial class Education : IPrimary { }

How can I disable required attribute on a property in a model in web api?

How to disable the [Required] attribute that has been set on a model property.
I tried with below code using new keyword but not working.
I also tried override keyword as well not worked.
ChildModel uses most of the properties of BaseModel that's instead of create new model file and code many similar properties I'm thinking to do something like this.
public class BaseModel
{
[Required]
public string Address{ get; set; }
}
public class ChildModel : BaseModel
{
public new string Address{ get; set; }
}
Any simple solution ?
Simply overriding or redeclaring using the new keyword on the property and removing the attribute does not work. The way I have always done this is like below.:
public abstract class BaseModel
{
public abstract string Address { get; set; }
}
public class ChildModel : BaseModel
{
[Required]
public override string Address { get; set; }
}
public class AnotherChildModel : BaseModel
{
//Not[Required]
public override string Address { get; set; }
}
You can read this thread if you want to know more on how attributes of a base class are treated during inheritance.

How to force EF Code First to ignore inheritance?

I've got a base class MyBase which is a part of my data model. I also have classes MyChild1, MyChild2 derived from it in related assemblies.
I want the children to be stored in database and loaded just like MyBase. Also I don't want my entity configuration to know anything about children classes.
Is there any way to force EF to ignore that inheritance and user only base class?
Thanks in advance
Here is your case:
public abstract class BaseModel
{
public int Id { get; set; }
public string Name { get; set; }
}
public partial class Child1 : BaseModel
{
public string Name1 { get; set; }
}
public partial class Child2 : BaseModel
{
public string Name2 { get; set; }
}
I guess your data should be similar like this (I am not sure your detail requirements, here is just an example):
public partial class Example<T> where T: BaseModel
{
public int Id { get; set; }
public T Data { get; set; } // so here could be any Child of BaseModel
}
public partial class Example: Example<BaseModel>
{
}
Use ModelBuilder.Ignore<>() Method to let EFCore ignore your children and base.
User PropertyBuilder.HasConversion Method to convert your data to/from database.
Here is sample code:
public class MyDbContext : DbContext
{
public virtual DbSet<Example> Examples { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
//Let EFCore ignore all models that you don't want it to be a table
builder.Ignore<BaseModel>();
builder.Ignore<Child1>();
builder.Ignore<Child2>();
builder.Entity<Example>(entity =>
{
entity.Property(p => p.Data).HasConversion(
x => JsonConvert.SerializeObject(x) //convert TO a json string
, x => JsonConvert.DeserializeObject<BaseModel>(x)//convert FROM a json string
);
});
}
}

Categories