how to implement navigational properties in nhibernate - c#

I have a scenario with a domain model used with NHibernate which looks kind of as below.
public class BaseClass
{
public virtual int Id { get; set; }
public virtual string SomeProperty { get; set; }
}
public class FirstClass : BaseClass
{
public virtual IList<AnotherClass> AnotherClassList { get; set; }
}
public class SecondClass : BaseClass
{
public virtual AnotherClass AnotherClass { get; set; }
}
public class AnotherClass
{
public virtual int Id { get; set; }
public virtual BaseClass MyNavigationalProperty { get; set; }
}
It look nice but it does not work as I was expecting it would do. This is my scenario;
As my first step I am saving my FirstClass with one or many AnotherClass in the list and it works perfectly. I could retrieve my FirstClass with my related AnotherClasses in the list.
In my second step I am saving a new AnotherClass separately and sets MyNavigationalProperty to my FirstClass from my first step. It do looks great, but...
In my final step I am retrieving my FirstClass and I am expecting that my AnotherClassList contains the AnotherClass from my second step. But I only get the original AnotherClasses from my first step.
Looking into the database I can see the record from my second step but there are two separate FKs in the table AnotherClass, BaseClass_Id and FirstClass_Id, and FirstClass_Id is NULL and therefore I don't get this record in my final step.
Is this wrong way to implement navigational properties? And, if so, how should I do it properly? Or... simply, is there a better way of doing this?
EDIT
From the question of mappings of Thilak I got another thought, The original domain model did not make use of a BaseClass, that is my implementation. Would that make it necessary to create my own mappings? Would that mean I have to totally abandon the automapping?

the reference uses another column as the collection. you can override it manually
class SetForeignKeyColumn : IAutomappingOverride<FirstClass>
{
public ...
{
instance.HasMany(x => x.AnotherClassList).KeyColumn("baseclass_id");
}
}

Related

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

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

Merge two properties to Entity Framework entity with partial class

I'm using Entity Framework.
My Customer Entity is:
public partial class Customer
{
public virtual int ID { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string CompanyName { get; set; }
}
And I have a BaseEntity class which is inherited by partial Customer class.
public class BaseEntity
{
public virtual int ID { get; set; }
}
public partial class Customer : BaseEntity
{
}
After that, I created a generic method as follows:
public static int GetId<T>(T entity) where T : BaseEntity
{
// id is zero after savechanges
var id = entity.ID;
return id;
}
My problem occurs when I want to get the id after SaveChanges() in the generic method, it's zero.
My test code is:
var db = new ContextDb();
db.Customers.Add(customer);
db.SaveChanges();
WriteLine($#"{customer.ID}"); // OK
WriteLine($#"{GetId(customer)}"); // Not OK --> ZERO
Thanks everyone for taking the time to try and help explain.
It is caused by the fact that, indeed, you have two ID fields: one (hidden) from BaseEntity (which has a value of zero) and one from Customer (which is not zero). Try to override the ID property or simply remove it from the Customer class declaration:
public partial class Customer
{
public override int ID { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string CompanyName { get; set; }
}
You can also mark the ID property and BaseEntity class as abstract to force to override the ID property in inherited classes:
public abstract class BaseEntity
{
public abstract int ID { get; set; }
}
NOTE: Previously accepted answer is not good advice, while it satisfies the issue, for new developers it encourages them to think that it is normal to make all properties virtual or common practice to override every virtual member from the base class.
Because BaseEntity already defines ID, you SHOULD NOT be trying to re-implement ID in the inheriting class unless you specifically want to augment the original implementation.
In this case we are not offering any different implementation to the base and so should not be trying to override it.
Conversely, if you do want to force every inheriting class to implement a function or property in their own way, then mark it as abstract, not virtual, and follow this advice.
Putting all 3 class definitions in-line, I would recommend the following solution:
public class BaseEntity
{
public int ID { get; set; }
}
public partial class Customer : BaseEntity
{
}
public partial class Customer
{
// ID is provided from the base!
//public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string CompanyName { get; set; }
}
Using virtual properties becomes dangerous as a design choice because there is a gray area where auto-properties might or might not be implemented in the base or other inheriting classes. If all classes in the inheritance tree use auto-properties, then there is no issue, however when any traditional getter or setter that is not auto is overriden, if the override does not call back to the base implementation, then any references to the fields or placeholders that were implemented in the base will not have their values set.
which is pretty close to the situation that OP has raised.
Specifically with ORM tools like EF, I would caution making the ID property virtual or abstract at all.
The ID is too important to leave to chance.
If you are using virtual properties to support Lazy Loading, in EF you only need to make navigational properties virtual to support this, not every property on a class.

Overriding abstract list<a> property with list<A>

I'm writing a piece of code to make certain reports. There are 4 types of reports which the user can request. Each type report is based on the base class 'report'. Each derived class has a List. The class 'A' is derived from base class 'a'.
Is it possible to add an abstract List to the 'report' class and let it be overridden by a List in the derived report classes? Something like this?
public abstract class Report
{
public abstract List<a> Coils { get; set; }
}
public class ProductionExitCoilReport : Report
{
public override List<A> Coils { get; set; }
}
public class a
{
public string SomeProperty { get; set; }
}
public class A: a
{
public string SomeOtherProperty { get; set; }
}
I'm kind of new to C# so if I'm asking something really basic or I have a big flaw in my thinking, please do point it out. But please don't just answer with yes or no.
Based on your description of the usage, there is no need to override the List/collection in your new class. Since A inherits from a, you can store objects of type A in "Coils". (due to polymorphism). Then if, at some later time, you want to access "SomeOtherProperty" of the objects of type A, you could use a cast.
public abstract class Report
{
public List<a> Coils { get; set; }
}
public class ProductionExitCoilReport : Report
{
}
public class a
{
public string SomeProperty { get; set; }
}
public class A : a
{
public string SomeOtherProperty { get; set; }
}
public void SomeMethod()
{
//to store the coil
ProductionExitCoilReport myReport = new ProductionExitCoilReport();
myReport.Coils.Add(new A());
//to retreive SomeOtherProperty from the first element in the list
string retrievedProperty = ((A)myReport.Coils[0]).SomeOtherProperty;
}
Your properties are readable and writable.
Derived types must always be compatible with the base type.
Every Report has Coils property that returns a read/write collections of items of type a. Thus you can always write report.Coils.Add(new a()).
ProductionExitCoilReport inherits from Report, so it would have been possible to run the same code - to add a (not A) to the collection returned by Coils: ((Report)productionReport).Coils.Add(new a()).
This contradicts what you want to accomplish.
Please read about covariance and contravariance:

Categories