entity framework multiple columns mapping - c#

I'm trying to implement database structure in which there are common fields i put them in a separate abstract class but i want to know if 3 classes are inheriting from same abstract class and 2 have same property name so, by default entity framework will add a numeric followed by property name in database. Is there any way to implement this separately. I've studied complex types and searched over internet but couldn't find any flexible solution. I'm sharing my code, please guide me
public abstract class GenericImpression
{
[Key]
public int ImpressionId { get; set; }
public DateTimeOffset ReportingDate { get; set; }
}
public class Impression : GenericImpression
{
public string InventorySource { get; set; }
public string Media { get; set; }
}
public class Impression21 : GenericImpression
{
public string InventorySource { get; set; }
}
Now, EF will add one table with InventorySource1 and InventorySource Column.

Use OfType<>.
Example:
_context.GenericImpressions.ofType<Impression21>().ToList()

Related

C# Change between specific data classes in DTO

We are getting data for our application.
We have common set of data with common fields, PurchaseDate, Manufacturer, PurchaseAmount,
Then we have specific subclass (which contains specific vehicle info, Aircraft wingspan, or car miles/per gallon, or Boat floatation metrics.
Instead of having classes which are not required, how can we create a model with a specific data type?
public class VehicleInfo
{
public Datetime PurchaseDate { get; set; }
public string Manufacturer { get; set; }
public int PurchaseAmount { get; set; }
// specific data, not all these needed
public AircraftInfo AircraftInfo {get;set;}
public CarInfo Carinfo {get;set;}
public BoatInfo BoatInfo {get;set;}
}
I read Dependency injection is not ideal practice for DTOs? https://softwareengineering.stackexchange.com/a/83166/354368
You can choose from "is-a" (inheritance) or "has-a" (composition).
You already have what is common to all vehicles
public class VehicleInfo
{
public Datetime PurchaseDate { get; set; }
public string Manufacturer { get; set; }
public int PurchaseAmount { get; set; }
}
So you can use inheritance (and make VehicleInfo abstract)
public class AircraftInfo : VehicleInfo
{
...
}
or use composition
public class AircraftInfo
{
public VehicleInfo VehicleInfo { get; set; }
...
}
or mix composition and inheritance
public class PassengerAircraftInfo : AircraftInfo
{
public PassengerVehicleInfo PassengerVehicleInfo { get; set; }
...
}
If you have e.g. 5 out of 10 vehicles that shares a set of common properties in addition to common properties you already have, inheritance will require another abstract class that inherits from VehicleInfo. Composition will require a new property on each of the 5 vehicles.
What is best, depends on final result of your analysis for the project. Number of inheritance levels should be kept to a minimum in order to keep code complexity low.

How to migrate a class using Generic enums with the Entity Framework Core?

How would you migrate this Car Class to a database using the Entity Framework?
I have a Main car class (which inherits from a Car Interface Class) with one Generic property called Part
public class Car<Parts> : GenericCarInterface
{
public Parts Part { get; set; }
}
Then I have several enums representing different parts that can be passed into the Generic Parts property of the Car Class
public enum VokswagenParts
{
VWWheels,
VWLights,
VWEngine
}
public enum TyotaParts
{
ToyotaSpoiler,
ToyotaAirFilter,
ToyotaBrakes
}
public enum FiatParts
{
FiatExhaust,
FiatSuspension,
FiatCVOuter
}
I envisage setting up an ApplicationDbContext as follows but the EF does not know what to make of the Part property
public class ApplicationDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(#"ConnectionStringHere");
}
public DbSet<GenericCarInterface> Cars { get; set; }
}
Any Ideas on the ways that this can be accomplished using Entity Framework Core?
Looking at your enums, it looks like each part has a unique name. if you don't mind whether your parts are grouped or not, you could put all your parts together in single enum.
public enum Parts {
VWWheels,
VWLights,
VWEngine,
ToyotaSpoiler,
ToyotaAirFilter,
ToyotaBrakes,
FiatExhaust,
FiatSuspension,
FiatCVOuter
}
then in your Car class you can do this
public Parts Parts { get; set; }
EF should be able to handle the rest.
I think i may have figured out a solution.
If i can create a separate class in my repository to hold the enum number values and the enum type names:
public class Car
{
public Guid CarId { get; set; }
public Part Part { get; set; }
}
public class Part
{
public Guid CarId { get; set; }
public Guid PartId { get; set; }
public int Enum { get; set; }
public string EnumName { get; set; }
}
Then I can persist that standard class to the database then simply re-compile the code back to the original Car class format just before transferring between layers
I might create a separate enum for the part names just to keep it strongly typed but I like the idea of having the names persisted not just enum numbers

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 { }

Fluent API - Configuring multiple instances of the same class within an entity

I have two classes below, Form and FormFieldOption<T>. The latter is intended to represent a set of <option> inside of a <select> in a web form that the Form object represents.
public class Form
{
public int Id { get; set; }
public FormFieldOption<string> Status { get; set; }
public FormFieldOption<string> Category { get; set; }
public FormFieldOption<int> Severity { get; set; }
}
public class FormFieldOption<T>
{
public int Id { get; set; }
public string Description { get; set; }
public bool Active { get; set; }
public T Value { get; set; }
}
I'm working on configuring these entities for Code-First like below:
public class FormFieldOptionStringConfiguration : EntityTypeConfiguration<FormFieldOption<string>>
{
public FormConfiguration()
{
//configure here
}
}
Unfortunately at this point I've discovered that I would like there to be a difference between the configuration for the Status and Category properties. I've not been able to figure out a way top configure the properties that utilize the FormFieldOption class individually. How could I do this?
Solutions I've come up with:
Create a new class that inherets FormFieldOption<T> for each property and configure individually.
Create an interface IFormFieldOption<T> and implement classes individually for each use.
I don't particularly care for either of these options as it feels like a lot of duplicated code just to create a different configuration for each table.
It turns out that you can't do this. What I ended up doing was creating a generic interface that I implemented for each property.

ICommentable interface in EF Code First - best practise

Suppose I have multiple unrelated object (classes) where I can not get common abstract class for (and therefore unique primary key for all such classes). I would also like to apply list of common objects to all such classes (say for example list of Comments). My first approach would be something like this:
public class Comment
{
public int Id { get; set; }
public string CommentContent { get; set; }
public virtual ICommentable CommentableObject { get; set; }
}
public interface ICommentable
{
ICollection<Comment> Comments { get; set; }
}
public class Page : ICommentable
{
public int Id { get; set; }
public string PageContent { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
public class Post : ICommentable
{
public int Id { get; set; }
public string PostContent { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
What EF code-first did, was creating single Comments table, with multiple nullable Foreign Keys (one for each related class) : Page_Id, Post_Id.
One of alternatives is to have separate Comments table for each class: PageComments, PostComments.
Is there any other more elegant solution to this common scenario ? Which one of two alternatives above is better ?
We're talking about an IsA (Is-A, Is A) relationship here. Your options are here: http://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph
they are essentially ways of mapping an is-a inheritance/implementation to an is-a database relationship. The second option (Table per Type) seems to do that in a way that is normalized, the third option I'm unfamiliar with.
In your case, if you're sure there will only be 2 ICommentable classes, you may want to stick with what you have. This will also allow you a bit more flexibility if you change your mind about them both implementing the same interface. Normalize 'till it hurts, denormalize 'till it works.

Categories