Fluent NHibernate Create entity mapping for overlapping entities - entity-framework

For eg. I have two tables in my database
NonResidentStudents - columns studentID, studentname, ModeOfTransport
ResidentStudents - columns studentID, studentname, DateOfJoiningHostel
studentID and studentName are common columns and the last column is uncommon between the two
For some reason, I cant change these tables or define a common master table and make uncommon columns in sub tables. So the table stucture is rigid.
Now when trying to create an entity and mapping for the above schema using FLUENT NHIBERNATE (only) I would like to know if I can define some sort of a common entity and common mapping for the common columns and create child entities inheriting from the common entities. In the child entity and mapping class I will have representations for the uncommon columns. Could anyone please share code of how to do it.

I did this before.
Common Class
public class BaseMapping : ClassMap<EntityBase>{
public BaseMapping ()
{
UseUnionSubclassForInheritanceMapping ();
// All the rest of the mapping attributes
}
}
For your individual classes that will inherit from the base you do this:
public class DepartmentMapping : SubclassMap<Department>
{
public DepartmentMapping ()
{
Abstract ();
// Map all the unique attributes
}
}
The code above will create one class based on Department and EntityBase. It will not create a table called EntityBase.

Related

Entity Framework navigation with only foreign key

Following the guide lines from Domain Driven Design, I try to avoid having one aggregate referencing a different aggregate. Instead, an aggregate should reference another aggregate using the other aggregate's id, for example:
public class Addiction
{
private Addiction(){} //Needed for EF to populate non-simple types
//DrugType belongs to the aggregate,
//inflate when retrieving the Addiction from the db
//EF does not need DrugId for navigation
Drug Drug{get;set;}
//The supplier is not part of the aggregate,
//aggregates only reference eachother using Ids
int SupplierId{get;set;}
//Other properties
}
public class AddictionConfiguration : IEntityTypeConfiguration<Addiction>
{
builder.HasOne(addiction => addiction.Drug); //Works
builder.HasOne("SupplierId") //Does not work.
}
In this (not very realistic) example, Drug is part of the Addiction's aggregate. When loading this entity from the database using EF, it will also inflate the Drug property without me having to specify the DrugId as the foreign key.
However, now I need to get a list of all Addictions and their suppliers by mapping the relevant properties to a Dto. I try to achieve this by using AutoMapper's ProjectTo functionality, e.g.
_mapper.ProjectTo<AddictionDto>(_dbContext.Addictions.Where(x => x.Id > 1));
where AddictionDto is defined as
public class AddictionDto
{
DrugDto Drug {get;set;}
SupplierDto Supplier {get;set;}
//other properties
}
And
public class SupplierDto
{
public int Id {get;set;}
public string Name {get;set;}
}
Automapper correctly loads the Addiction and also the Drug, but I cannot get it to load the Supplier. I've tried all the options of the IEntityTypeConfiguration to tell EF that there is a navigation property, but I cannot get it to work. Does anyone know if is even possible to do what I described above?

Best JPA Inheritance option to implement the following requirement

Having the following kind of table tables. What will be the good approach to persist these tables? Used inheritance strategy for this, but it didn't work as expected.
Requirement 1: Need to persist student table, it will persist the member as well as address table as well
Requirement 2: Need to persist teacher table, it will persist the member as well as address table as well
Need to perform get, update and delete option on these tables.
Member {
member_id - have one to one relation with student id and teacher id
lastupdateddate
latupdatedby
}
Student {
student id - have one to one relation with member id
student name
lastupdateddate
latupdatedby
}
teacher {
teacher id - have one to one relation ship with member
teacher name
lastupdateddate
latupdatedby
}
address {
address id
member_id - have one to one relationship with member class
lastupdateddate
latupdatedby
}
When I persist/update student details, the address related info is not properly inserted or updated.When I check insert queries fired on member, then student table after on address table. But, in the insert query to address table, the member_id value is coming as null.Because of this only address table is not populated.
Entity structure is is as given below
public abstract class Member implements Serializable {
}
public class Student extends member implements Serializable {
}
public class Teacher extends member implements Serializable {
}
public class Address implements Serializable {
}
The mapping is mentioned as given below. Tried out various available options.
In member entity class
#Access(AccessType.PROPERTY)
#OneToOne(mappedBy="member", cascade=CascadeType.ALL)
public Address getAddress() {
return postalAddress;
}
In address entity class
#OneToOne(fetch=FetchType.LAZY)
#JoinColumn(name = "MEMBER_ID")
private Address address;
It looks like you have 2 options:
InheritanceType.JOINED. It's almost what you've described: common part is in one table, different parts are in different tables. On each request JOIN will occure
InheritanceType.SINGLE_TABLE. Here all the data will be stored in single table and descriminator will be used to determine if record if for student or for teacher.
Personally I would prefer second options because you have almost all fields in common, also most of operations are lighter and involve WHERE, not JOIN.

Is it Possible to Use EF Core in an MVC site Using Just One Table?

Say I have a table in the database with data already populated (imported from excel).
I am building an MVC website using .NET Core and EF Core (both v.1.1.2)
What I'm wanting to do create a series of models, whose data is derived from one original "source data" table. The source data table has 150 columns, and although I don't need them all right now, I do want to retain all columns so that I might be able to use them at a later time if needed.
Using the "dotnet ef dbcontext scaffold" command, I was able to generate a:
Model - with all public get/set properties for each column
DbContext Class - with DbSet & Fluent API statements to reference the table and columns
With this setup, is it possible to setup a sort of "virtual" relational data model with EF Core by simply creating various Model classes (many-to-many relationships) and their properties equal to the properties already defined in the original "source" entity?
What I'm hoping to avoid is having to maintain an actual relational data structure in the DB (independent tables linked by PKs, FKs, join tables, etc.)
Reason being... I'll only be looking to do a nightly update of the source data table from bulk import of Excel worksheet and will not have to persist or track any changes to the data (read only). So, I'd like to not have to deal with the additional overhead/setup/maintenance involved with mapping the source data to relational tables, columns, keys, etc. during the import.
Can I simply create various models, then in the DbContext, override the OnModelCreating method passing an instance of modelBuilder to map those DbSet entities to the columns in the source table?
namespace VTracker.Contexts
{
public partial class DataContext : DbContext
{
public DataContext(DbContextOptions options) : base(options)
{
}
public DbSet<SourceData> Data { get; set; }
public DbSet<SomeModel1> Model1 { get; set; }
public DbSet<SomeModel2> Model2 { get; set; }
public DbSet<SomeModel3> Model3 { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<SourceData>(entity =>
{
// some key must be defined?
entity.HasKey(e => e.SourceIDColumn);
entity.ToTable("SourceDataTable");
entity.Property(e => e.SourceIDColumn)
entity.Property(e => e.SourceColumn1)
.HasColumnName("SourceColumn1")
// ...... continue mapping .....
// Some Model 1 Entity Builder
entity.ToTable("SourceDataTable");
// ...... continue mapping .....
// Some Model 2 Entity Builder
entity.ToTable("SourceDataTable");
// .... and so on for other models......
}
}
}
}
Or would it be better to just use the one entity for everything and just build out SQL / LINQ queries to retrieve/join the data as needed?

Add Column Name Convention to EF6 FluentAPI

This question was asked here 4 years ago: EF Mapping to prefix all column names within a table I'm hoping there's better handling these days.
I'm using EF6 Fluent API, what I'll call Code First Without Migrations. I have POCOs for my models, and the majority of my database column names are defined as [SingularTableName]Field (e.g., CustomerAddress db column maps to Address field in Customers POCO)
Table:
CREATE TABLE dbo.Customers (
-- ID, timestamps, etc.
CustomerName NVARCHAR(50),
CustomerAddress NVARCHAR(50)
-- etc.
);
Model:
public class Customer
{
// id, timestamp, etc
public string Name {get;set;}
public string Address {get;set;}
}
ModelBuilder:
modelBuilder<Customer>()
.Property(x => x.Name).HasColumnName("CustomerName");
modelBuilder<Customer>()
.Property(x => x.Address).HasColumnName("CustomerAddress");
Goal:
What I'd really like is to be able to say something like this for the FluentAPI:
modelBuilder<Customer>().ColumnPrefix("Customer");
// handle only unconventional field names here
// instead of having to map out column names for every column
With model-based code-first conventions this has become very simple. Just create a class that implements IStoreModelConvention ...
class PrefixConvention : IStoreModelConvention<EdmProperty>
{
public void Apply(EdmProperty property, DbModel model)
{
property.Name = property.DeclaringType.Name + property.Name;
}
}
... and add it to the conventions in OnModelCreating:
modelBuilder.Conventions.Add(new PrefixConvention());

JPA mapping of multiple attributes of the same type

I am learning JPA (2.0) and I would like to understand how to properly map multiple attributes of the same class type. For instance, pretend I have a model:
#Entity
class Person {
String name;
int age;
// getters/setters
}
#Entity
class Family {
Person dad;
Person mom;
List<Person> children;
// getters/setters
}
How can I properly map mom and dad attributes?
Thanks and sorry if it is too basic. Couldn't find an answer anywhere.
The fact that you have two instances doesn't change anything.
You map dad and mom each as a ManyToOne association, and there will be two join columns in the family table: one for dad and one for mom.
You map children as a OneToMany (assuming a child can only be a child in one family), and there will be either a join table between Family and Person (the default for a unidirectional OneToMany), or a join column in the Person table referencing the family table (the default for a OneToMany bidirectional association).