NHibernate derived base class - c#

we have a NHibernate Entity called Order. The Order has a List of Positions and some other stuff.
I now implemented a new Entity called OrderMin, which is now a base class of the Order. The same I did for the OrderPosition, which has now a base class called OrderPositionMin
When I try to load an OrderMin-Collection, I get a strange behavior:
In the collection, there are now OrderMin and Order objects, this is my Code:
var mins = Session.QueryOver<OrderMin>()
.Where(x => RestrictionExtensions.IsIn(x.Id,
list))
.List();
When I take a look in the collection, the containing Order objects has now 2 Lists Positions Lists. One is from the type OrderPosition and one from OrderPositionMin.
I tried to use the override keyword in the Order Object, but this is not possible due all Properties must be virtual.
Does anyone have an idea what's going wrong here?
Thanks in advance,
Dennis

This is a default behavior in NHibernate. You need to declare a base class from which your Order and OrderMin derive.
public abstract class OrderBase
{
// The properties that are needed by all derived types
}
public class OrderMin : OrderBase {}
public class Order : OrderBase {}
After that, your query result should look like you expect it.
If you query a base class, NHibernate will materialize all entities of the base class and all entities of the derived types.

Related

assign two classes to a generic constraint at runtime

I want to assign two classes to generic constraint at runtime using an OR condition. I don't know if it is possible or not, as I am relatively new to all this.
public interface IGenericRepository<TEntity> where TEntity : Employee Department
I want to assign TEntity either Employee class or Department class. Employee & Department are my two entities in DbContext. Please help me out on this one. Thank you in advance.
My first recommendation is: Do not use another generic repository on top of Entity Framework, because it already implements one.
In the other hand, I have seen cases where this make sense. If you are in one of those cases, consider using Generic Repository only for the things that you could apply to every single class of your model. As soon as your model object requires an special query, then create it's own repository for it.
for example, it might be that for Department you only do a ListAll(), then use a generic repository.
But let's imagine that for employee you might want to do more complex things, like ListAllEmployessUnderBossThatAreOnHolidays(Employee boss)
Then you could have this structure:
// All model classes inherit from this one
public class ModelObject
{}
public class Employee: ModelObject
{}
public class Department: ModelObject
{}
// This repository could be use for simple model objects that do simple operations
// For example, -ALL- Department operations are simple, and it never requires a
// complex query. So i handle it with this repository to avoid code duplication with
// other model objects that are also simple
public class IGenericRepository<TEntity> where TEntity : ModelObject
{ }
// Employee has some complex queries, so I create a repository for it that might or
// might not inherit from IGenericRepository
public class EmployeeRepository : IGenericRepository<Employee>
{ }

Is it possible to create variable in parent class, that would initialized once per derrived type?

I'm using IDataErrorInfo interface to validate my entities. As long as validation logic is reading metadata from attributes, it is the same for all entities, so I've created class
public class DataErrorInfo : IDataErrorInfo
And all entities are derriving from it. Thing is, that I wish to cache reflection info for derived classes to speed up validation, so every entity type should initialize this cache once per running application.
I was thinking to use static readonly field, but found out, that it is initialized with first used entity type's reflection info, so if there's entity A and entity B, and entity A is accessed first, entity B will have entity A reflection cache.
You could use a Dictionary<Type, DataErrorInfo> implemented as a Singleton.
The Singleton pattern enforces that only one Dictionary exists in memory. The Dictionary itself will enforce the constraint that each type gets one entry as a Key. Your Value is going to be whatever reflection info you want cached. In this case it looks like that's DataErrorInfo.
In a generic class if you have a static it's for the closed generic type you can leverage this.
Define your base class as a generic (with a somewhat odd looking but valid constraint)
public class DataErrorInfo<T> : IDataErrorInfo where T : DataErrorInfo<T>{
...
}
you then define your derived class like this (notice that the derived class itself is passed as T to the base generic type)
public class EntityClass : DataErrorInfo<EntityClass>{
...
}
that way any static is scoped to the derived class not the parent class as long as you don't do as below
public class AnotherEntityClass : DataErrorInfo<EntityClass>{
...
}

Using generics in a business object and collection

I have a base object abstract class and a base object collection class for some business objects to inherit from. I'm trying to figure out how to pass the base object type to the collection class (and other methods). I've been able to solve this by wrapping the class in an interface but i'm wondering if there is another way to do this or if using an interface is the best way. i think my question might make more sense from the code below.
i have a base class define -
public abstract class BaseObject<TYPE,KEY>:where TYPE:BaseObject<TYPE,KEY>, new()
public KEY ObjectId {get;protected set; }
i have a class that inherits from BaseObject
public class Customer : BaseObject<Customer,Guid>
My base collection class is -
public abstract class BaseObjectCollection<T> : List<T> where T: BaseObject, new()
I also have a few methods in other class that want to reference this baseclass -
public bool ValidateRule(BaseObject dataObject) {etc...}
If you use the base class in other classes that are not also generics, then I'm afraid that you're going to have to specify the type and key parameters for the object when you pass it to methods like ValidateRule.
In this design, an Interface implemented by the base object is probably the most appropriate solution. We use this pattern extensively in our code and it works quite well.
One other item you could explore is reducing the complexity of the base class slightly by moving the Key into the class as an overridable (or must override) property that defaults to a string or int or whatever may be appropriate. We found that this approach (we forced all collection keys to be strings) significantly reduced the class complexity.

C# Abstract Method Inheritance and Hiding Methods Unintentionally

I've got a question about accidentally hiding abstract methods.
I'm creating a basic Entity class as an interface from which to create all other entities in the game I'm working on.
From this Entity class, I have created several derived classes. There are things like MovingEntity, Trigger, Door, etc... Many of these children classes also have children derived from them. For example, MovingEntity has classes like Projectile and EnemyUnit as children.
In my base Entity class, I have methods like Update() and Render() that are abstract, because I want every entity to implement these methods.
Once I get down to the second level, however, -that's- where I hit my question/problem. I'll use the Trigger class, for example. Trigger derives from the base Entity class, but Trigger still has its own children (like TriggerRespawning and TriggerLimitedLifetime). I don't want to instantiate a Trigger object, so I can keep that class abstract - I will only create objects from Trigger's children classes. But what do I do with the abstract methods that Trigger is supposed to implement from Entity?
I thought I could just basically use the same code in Trigger as I did in Entity. Declare the same method, same name, same parameters, and just call it abstract. Then, Trigger's children would be forced to implement the actual functions.
This didn't work, however, because in the Trigger class, my build errors say that I am hiding the abstract methods from the base Entity class.
How can I pass down the idea of forcing the eventual children to implement these abstract methods without making all of the parents in-between implement them? Do I need to use virtual on the first round of children classes?
I haven't been able to find a good answer on this so far, so I decided to break down and ask. Thanks in advance, guys.
Just don't redeclare the methods at all - the eventual concrete classes will have to implement all the abstract methods still unimplemented all the way up the tree:
public abstract class Foo
{
public abstract int M();
}
public abstract class Bar : Foo
{
// Concrete methods can call M() in here
}
public class Baz : Bar
{
public override int M() { return 0; }
}

Extending an object and any child collections?

I have an class named Foo. This class contains a collection of child objects of type FooChildBase, but I also have a further class of type FooChildTwo which inherits from FooChildBase.
Class Foo
Public Children As IList(Of FooChildBase)
End Class
Class FooChildBase
Public Info As String
End Class
Class FooChildTwo
Inherits FooChildBase
Public ExtraInfo As String
End Class
This all works fine. Now I need to use a specialisation of my Foo object with extra information.
Class FooSpecial
Inherits Foo
Public SpecialInfo As String
End Class
Class FooChildSpecial
Inherits FooChildBase
Public SpecialChildInfo As String
End Class
What I would like to do is have my FooSpecial Class treat it's Children collection as if they were FooChildSpecial objects, but still be able to add FooChildTwo objects to it. Is this possible and if so how can it be done?
EDIT
I think my original question was incorrect. I need to FooChildSpecial class to wrap any of the objects in the Children collection with the extra values, whether they are FooChildBase or FooChildTwo or XXX.
Hope this makes sense! Please let me know if more clarification is needed.
James
In order for FooSpecialChild to "Wrap" FooChildTwo, it either has to inherit from it or implement the same interface (IFooChildTwo). Unfortunately, you cannot conditionally inherit or implement ... it is either always or never. As such, your FooSpecialChild class can inherit from FooChildTwo, but then it will always be a FooChildTwo. Same if it implements the same interface as FooChildTwo.
The design pattern you laid out will work correctly. Since both FooChildSpecial and FooChildTwo inherit from the same base class, and the list is of that base class type, it will work out. You'll just have to check the type of the object when you're pulling from the .Children property.
After copy+pasting your code into a sample project, I could successfully do:
var foo = new Foo();
foo.Children = new List<FooChildBase>();
var special = new FooChildSpecial();
special.SpecialChildInfo = "special";
foo.Children.Add(special);
var two = new FooChildTwo();
two.ExtraInfo = "two";
foo.Children.Add(two);
Which shows that you can add both FooChildSpecial and FooChildTwo to your original list.
What do you mean by "treat as if they were FooChildSpecial" objects? Do you mean access methods that exist only in FooChildSpecial objects?
In this case you will need to cast them to FooChildSpecial.
However, it is better to just let FooSpecial treat them as FooChildBase objects, but have in FooChildSpecial and FooChildTwo that override the base methods to get different behaviors for the two subclasses.
I also have a feeling that you really don't need the FooSpecial class at all, but I could be wrong. I suspect that the extra information and special information could just be combined into "information" and if they need different types of information to initialize the class wtih the different types.
You could purhaps do it with generics that you have a base class which contains a list of Type T. When you define Foo and FooSpecial you spesify what T is.

Categories