How to use NHibernate DiscriminateSubClassesOnColumn and References for the same column - nhibernate

The Setup
I am using FluentNHibernate 1.4.0 for my NHibernate 3.3.3-SP1 mappings in a .NET4.0 library. I'm using the "table-per-inheritance" approach for my type hierarchy as follows:
-- Different process types potentially use
-- different types of reference values
CREATE TABLE ProcessTypes
(Id INT PRIMARY KEY)
-- Contains reference values for value comparisons
CREATE TABLE ProcessReferenceValues
(Id INT PRIMARY KEY IDENTITY(1,1),
ProcessTypeId INT FOREIGN KEY REFERENCES ProcessTypes(Id),
FloatReferencesValue FLOAT NULL,
IntReferenceValue INT NULL)
// POCOs
class ProcessReferenceValues
{
public virtual int Id { get; set; }
public virtual ProcessTypes ProcessType { get; set; }
public virtual float? FloatReferenceValue { get; set; }
public virtual int? IntReferenceValue { get; set; }
}
class IntProcessReferenceValues : ProcessReferenceValues { }
class FloatProcessReferenceValues : ProcessReferenceValues { }
enum ProcessTypeName : int
{
IntProcess = 1,
FloatProcess = 2
}
class ProcessTypes
{
public virtual int Id { get; set; }
public virtual ProcessTypeName Name { get; set; }
}
// FluentNHibernate Mappings
class ProcessReferenceValuesMap
: FluentNHibernate.Mapping.ClassMap<ProcessReferenceValues>
{
public ProcessReferenceValuesMap()
{
string processTypeId = "ProcessTypeId";
this.Id(x => x.Id);
this.Map(x => x.FloatReferenceValue).Nullable();
this.Map(x => x.IntReferenceValue).Nullable();
// Here is the tricky bit
this.References(x => x.ProcessType, processTypeId);
this.DiscriminateSubClassesOnColumn(processTypeId);
}
}
class IntProcessReferenceValuesMap
: FluentNHibernate.Mapping.SubclassMap<IntProcessReferenceValues>
{
public IntProcessReferenceValuesMap()
{
this.DiscriminatorValue((int)ProcessTypeName.IntProcess);
}
}
class FloatProcessReferenceValuesMap
: FluentNHibernate.Mapping.SubclassMap<FloatProcessReferenceValues>
{
public FloatProcessReferenceValuesMap()
{
this.DiscriminatorValue((int)ProcessTypeName.FloatProcess);
}
}
class ProcessPeriodTypesMap : FluentNHibernate.Mapping.ClassMap<ProcessPeriodTypes>
{
public ProcessPeriodTypesMap()
{
this.ReadOnly();
this.Id(x => x.Id, "id");
this.Map(x => x.Name, "id").ReadOnly().CustomType<PeriodTypeName>();
}
}
The Problem
While reading from the database works like a charm - the appropriate sub classes are selected correctly - saving a new process reference value gives me an exception:
// Reading
var processType =
(from type in session.Query<ProcessTypes>()
where type.Name == ProcessTypeName.IntProcess
select type).FirstOrDefault(); // OK, finds the IntProcess
var referenceValues =
(from val in session.Query<ProcessReferenceValues>()
select val).ToList(); // OK, finds the appropriate subclasses
// Inserting
var processType = new ProcessTypes
{
Id = (int)ProcessTypeName.IntProcess
};
var referenceValue = new ProcessReferenceValues
{
FloatReferenceValue = 0.7f,
IntReferenceValue = null,
ProcessType = processType // Needs the appropriate ProcessType
};
session.Save(referenceValue); // <- BOOM!
Error dehydrating property value for ProcessReferenceValues.ProcessType
Invalid Index 2 for OleDbParameterCollection with Count=2.
bei System.Data.OleDb.OleDbParameterCollection.RangeCheck(Int32 index)
bei System.Data.OleDb.OleDbParameterCollection.GetParameter(Int32 index)
bei System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item(Int32 index)
bei NHibernate.Type.Int32Type.Set(IDbCommand rs, Object value, Int32 index) in p:\nhibernate-core\src\NHibernate\Type\Int32Type.cs:Zeile 60.
bei NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index) in p:\nhibernate-core\src\NHibernate\Type\NullableType.cs:Zeile 182.
bei NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) in p:\nhibernate-core\src\NHibernate\Type\NullableType.cs:Zeile 122.
bei NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) in p:\nhibernate-core\src\NHibernate\Type\ManyToOneType.cs:Zeile 50.
bei NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) in p:\nhibernate-core\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:Zeile 2410.
As always in hard times I summoned the gooragle and the problem seems to be that the this.DiscriminateSubClassesOnColumn(processTypeId) adds a conflict with the this.References(x => x.ProcessType, processTypeId) mapping. When I remove the former the insert is successful but I want the subclass mapping AND I also need to be able to set the ProcessReferenceValues.ProcessType when adding new instances of ProcessReferenceValues to distinguish the subclasses.
The Question
Is it possible to discriminate subclasses on a column and at the same time referencing that same column on the same type?
Help very much appreciated, there's got to be a way to do this ...
thx in advance!

classes and mappings without the problem
// POCOs
class ProcessValue
{
public virtual int Id { get; set; }
public abstract ProcessValueType Type { get; }
}
class IntProcessValue : ProcessValue
{
public virtual int? Value { get; set; }
public override ProcessValueType Type { get { return ProcessValueType.Int; } }
}
class FloatProcessValue : ProcessValue
{
public virtual float? Value { get; set; }
public override ProcessValueType Type { get { return ProcessValueType.Float; } }
}
enum ProcessValueType : int
{
Int = 1,
Float = 2
}
// FluentNHibernate Mappings
class ProcessValueMap : ClassMap<ProcessValue>
{
public ProcessValueMap()
{
string processTypeId = "ProcessValueTypeId";
Id(x => x.Id);
// just so you can query by type enum also. Querying by clr Type is already implemented
Map(x => x.Type, processTypeId).CustomType<ProcessValueType>().ReadOnly().Access.None();
DiscriminateSubClassesOnColumn(processTypeId);
}
}
class IntProcessValueMap : SubclassMap<IntProcessValue>
{
public IntProcessValueMap()
{
Map(x => x.Value).Nullable();
DiscriminatorValue((int)ProcessValueType.Int);
}
}
class FloatProcessValueMap : SubclassMap<FloatProcessValue>
{
public FloatProcessValueMap()
{
Map(x => x.Value).Nullable();
DiscriminatorValue((int)ProcessValueType.Float);
}
}

Related

One-to-one relationship in NHibernate using composite key

I'm trying to figure out the proper way to model a one-to-one (or one-to-zero) relationship in NHibernate, or indeed to learn categorically whether such a thing can be done.
Currently I have two models, Document and ScriptDocument whereby there should be a bidirectional relationship between the two, defined by a composite primary key made up of two properties that are shared/duplicated across both tables. A Document may have zero or one associated ScriptDocument and every ScriptDocument will have an associated Document. They both have a shared primary key made up of two properties: a string ("key") and int ("userref").
Currently I've set up my models and mappings as follows:
public class Document
{
public virtual string Key { get; set; }
public virtual int UserRef { get; set; }
public virtual ScriptDocument ScriptDocument { get; set; }
// ... other properties ...
public override bool Equals(object obj)
{
return obj is Document document &&
Key == document.Key &&
UserRef == document.UserRef;
}
public override int GetHashCode()
{
return HashCode.Combine(Key, UserRef);
}
}
public class DocumentMap : ClassMapping<Document>
{
public DocumentMap()
{
Schema("Documents");
Table("Documents");
ComposedId(m =>
{
m.Property(x => x.Key);
m.Property(x => x.UserRef, m => m.Column("User_Ref"));
// the PK fields are named slightly differently across the two tables. Same data types though and same names in the models.
});
OneToOne(x => x.ScriptDocument, m => {
m.Cascade(Cascade.All);
m.Constrained(false);
});
// ... other property mappings ...
}
}
public class ScriptDocument
{
public virtual string Key { get; set; }
public virtual int UserRef { get; set; }
public virtual Document Document { get; set; }
// ... other properties ...
public override bool Equals(object obj)
{
return obj is ScriptDocument sd &&
Key == sd.Key &&
UserRef == sd.UserRef;
}
public override int GetHashCode()
{
return HashCode.Combine(Key, UserRef);
}
}
public class ScriptDocumentMap : ClassMapping<ScriptDocument>
{
public ScriptDocumentMap()
{
Table("Script_Document");
ComposedId(m =>
{
m.Property(x => x.Key, m => m.Column("DocKey"));
m.Property(x => x.UserRef);
});
OneToOne(x => x.Document, m => m.Constrained(true));
// ... other property mappings ...
}
}
At this point, NHibernate seems happy with these models and mapping definitions, but the problem is that the relationships seem to be effectively ignored. When loading one or more Document entities, they all have a null ScriptDocument property and the same is true of the Document property on any ScriptDocument entities.
As far as I can tell, NHibernate isn't even attempting to fill those properties in any cases. I therefore assume one of two things is happening:
I've done something wrong (probably in the mappings). I'm sort of hoping there's just one or two little things I've missed, but I can't for the life of me work out what that might be.
This can't actually be done. My understanding is that this approach should be just fine if we had a single shared primary key but I'm not sure whether the shared composite key is something we can do. I can't find any comparable examples.
Note about this approach: you definitely don't need to tell me how unorthodox this is 😅 I'm painfully aware. But I'm working within the constraints of pre-existing systems. Unless this absolutely, categorically, isn't possible, this is the approach that I'd like to continue with at this point.
So the key to solving this seemed to be to use a component composite ID.
I added the following class to define the composite primary key for both tables:
[Serializable]
public class DocumentIdentifyingKey
{
public virtual string Key { get; set; }
public virtual int UserRef { get; set; }
public override bool Equals(object obj)
{
return obj is DocumentIdentifyingKey key &&
Key == key.Key &&
UserRef == key.UserRef;
}
public override int GetHashCode()
{
return HashCode.Combine(Key, UserRef);
}
public override string ToString()
{
return $"{UserRef}/{Key}";
}
}
And was then able to update the entity model classes and associated mappings as follows, using ComponentAsId defining the actual database fields for the identities for each of the two classes/tables:
public class Document
{
public virtual DocumentIdentifyingKey Identity { get; set; }
public virtual ScriptDocument ScriptDocument { get; set; }
// ... other properties ...
public override bool Equals(object obj)
{
return obj is Document document &&
Identity == document.Identity;
}
public override int GetHashCode()
{
return Identity.GetHashCode();
}
}
public class DocumentMap : ClassMapping<Document>
{
public DocumentMap()
{
Schema("Documents");
Table("Documents");
ComponentAsId(x => x.Identity, m => {
m.Property(i => i.Key);
m.Property(i => i.UserRef, m => m.Column("User_Ref"));
});
OneToOne(x => x.ScriptMetadata, m => {
m.Cascade(Cascade.All);
m.Constrained(false);
m.Fetch(FetchKind.Join);
m.Lazy(LazyRelation.NoLazy);
});
// ... other property mappings ...
}
}
public class ScriptMetadata
{
public virtual DocumentIdentifyingKey Identity { get; set; }
public virtual Document Document { get; set; }
// ... other properties ...
public override bool Equals(object obj)
{
return obj is ScriptMetadata sd &&
Identity == sd.Identity;
}
public override int GetHashCode()
{
return Identity.GetHashCode();
}
}
public class ScriptDocumentMap : ClassMapping<ScriptMetadata>
{
public ScriptDocumentMap()
{
Table("Script_Document");
ComponentAsId(x => x.Identity, m =>
{
m.Property(i => i.Key, m => m.Column("DocKey"));
m.Property(i => i.UserRef);
});
OneToOne(x => x.Document, m => {
m.Constrained(true);
m.Fetch(FetchKind.Join);
m.Lazy(LazyRelation.NoLazy);
});
// ... other property mappings ...
}
}
I'm not entirely sure why this worked but having the identity of the document expressed as an instance of an object rather than just the combination of the two fields on each class seemed to be the key incantation which allowed NHibernate to understand what I was getting at.
Note: in this solution, I've added Fetch and Lazy calls to the two OneToOne relationships. These are not specifically part of this solution but instead were added to better instruct NHibernate what load behaviour would be preferred.

NHibernate - Is it possible to map columns into collection composite objects

Using NHibernate is it possible to map columns in a table to a collection of objects.
For example if I have a very badly designed database table with columns as such:
ClientID
ClientName
First_AmountPaid
Second_AmountPaid
Third_AmountPaid
Fourth_AmountPaid
Is it possible to map this to the following class structure where First_AmountPaid through to Fourth_AmountPaid have their own class implementation?
public class Client
{
public int ClientId { get; set; }
public string ClientName { get; set; }
public IList<AmountPaid> Amounts { get; set; }
}
public class AmountPaid
{
public decimal Amount { get; set; }
}
public class FirstAmountPaid : AmountPaid{ }
public class SecondAmountPaid : AmountPaid{ }
public class ThirdAmountPaid : AmountPaid{ }
public class FourthAmountPaid : AmountPaid{ }
Therefore giving a more meaningful code structure.
Thank you
i'm not sure why there are subclasses when the listposition already defines the order of the amounts
Map(x => x.Amounts)
.Columns.Add("First_AmountPaid", "Second_AmountPaid", "Third_AmountPaid", "Fourth_AmountPaid")
.CustomType<AmountPaidType>();
class AmountPaid : IUserType
{
public object Assemble(object cached, object owner)
{
return cached;
}
public object DeepCopy(object value)
{
return ((IList<AmountPaid>)x).Select(a => a.Clone()).ToList();
}
public object Disassemble(object value)
{
return value;
}
bool IUserType.Equals(object x, object y)
{
// assuming AmountPaid implements Equals
return ((IList<AmountPaid>)x).SequenceEquals((IList<AmountPaid>)y);
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
public bool IsMutable
{
get { return true; }
}
public void NullSafeSet(cmd, value, index)
{
var list = (IList<AmountPaid>)value;
NHibernateUtil.Double.NullSafeSet(cmd, list[0].Amount, index);
NHibernateUtil.Double.NullSafeSet(cmd, list[1].Amount, index + 1);
NHibernateUtil.Double.NullSafeSet(cmd, list[2].Amount, index + 2);
NHibernateUtil.Double.NullSafeSet(cmd, list[3].Amount, index + 3);
}
public object NullSafeGet(rs, names, owner)
{
var list = new List<AmountPaid>();
foreach (var name in names)
{
list.Add(new AmountPaid((double)NHibernateUtil.Double.Get(rs, name)));
}
return list;
}
public object Replace(object original, object target, object owner)
{
return original;
}
public Type ReturnedType
{
get { return typeof(IList<AmountPaid>); }
}
public SqlType[] SqlTypes
{
get { return new[] { SqlTypeFactory.Double, SqlTypeFactory.Double, SqlTypeFactory.Double, SqlTypeFactory.Double }; }
}
}

Fluent NHibernate Insert Null FK

I have a table mapping with nullable FK constraint. In my fluent mapping I am doing something like so:
public enum PlayerPosition
{
None = 0,
Forward = 1
//etc
}
Entity
public virtual PlayerPosition? Position { get; set; }
Map(x => x.Position).Column("PlayerPositionId").CustomType< PlayerPosition>();
What I would like to happen is when PlayerPosition is set to "None" Nhibernate will insert null. I am not sure how to make that happen.
i would go for IUserType:
public virtual PlayerPosition Position { get; set; }
Map(x => x.Position).Column("PlayerPositionId").CustomType<PlayerPositionUserType>();
class PlayerPositionUserType : IUserType
{
public object NullSafeGet(IDBReader reader, string[] names, object owner)
{
int? positionvalue = NHibernateUtil.Int32.NullSafeGet(reader, names[0]);
return (positionvalue.HasValue) ? (PlayerPosition)positionvalue : PlayerPosition.None;
}
public void NullSafeSet(IDBCommand cmd, object value, int index)
{
var position = (PlayerPosition)value;
if (position == PlayerPosition.None)
NHibernateUtil.Int32.NullSafeSet(cmd, null, index);
else
NHibernateUtil.Int32.NullSafeSet(cmd, (int)position, index);
}
public Type ReturnType
{
get { return typeof(PlayerPosition); }
}
public SqlType[] SqlTypes
{
get { return new [] { SqlTypeFactory.Int32 } }
}
}

Fluent NHibernate compositeid to mapped class

I'm trying to figure out how to use CompositeId to map another class. Here's a test case:
The tables:
TestParent:
TestParentId (PK)
FavoriteColor
TestChild:
TestParentId (PK)
ChildName (PK)
Age
The classes in C#:
public class TestParent
{
public TestParent()
{
TestChildList = new List<TestChild>();
}
public virtual int TestParentId { get; set; }
public virtual string FavoriteColor { get; set; }
public virtual IList<TestChild> TestChildList { get; set; }
}
public class TestChild
{
public virtual TestParent Parent { get; set; }
public virtual string ChildName { get; set; }
public virtual int Age { get; set; }
public override int GetHashCode()
{
return Parent.GetHashCode() ^ ChildName.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj is TestChild)
{
var toCompare = obj as TestChild;
return this.GetHashCode() != toCompare.GetHashCode();
}
return false;
}
}
The Fluent NHibernate maps:
public class TestParentMap : ClassMap<TestParent>
{
public TestParentMap()
{
Table("TestParent");
Id(x => x.TestParentId).Column("TestParentId").GeneratedBy.Native();
Map(x => x.FavoriteColor);
HasMany(x => x.TestChildList).KeyColumn("TestParentId").Inverse().Cascade.None();
}
}
public class TestChildMap : ClassMap<TestChild>
{
public TestChildMap()
{
Table("TestChild");
CompositeId()
.KeyProperty(x => x.ChildName, "ChildName")
.KeyReference(x => x.Parent, "TestParentId");
Map(x => x.Age);
References(x => x.Parent, "TestParentId"); /** breaks insert **/
}
}
When I try to add a new record, I get this error:
System.ArgumentOutOfRangeException :
Index was out of range. Must be
non-negative and less than the size of
the collection. Parameter name: index
I know this error is due to the TestParentId column being mapped in the CompositeId and References calls. However, removing the References call causes another error when querying TestChild based on the TestParentId.
Here's the code that does the queries:
var session = _sessionBuilder.GetSession();
using (var tx = session.BeginTransaction())
{
// create parent
var p = new TestParent() { FavoriteColor = "Red" };
session.Save(p);
// creat child
var c = new TestChild()
{
ChildName = "First child",
Parent = p,
Age = 4
};
session.Save(c); // breaks with References call in TestChildMap
tx.Commit();
}
// breaks without the References call in TestChildMap
var children = _sessionBuilder.GetSession().CreateCriteria<TestChild>()
.CreateAlias("Parent", "p")
.Add(Restrictions.Eq("p.TestParentId", 1))
.List<TestChild>();
Any ideas on how to create a composite key for this scenario?
I found a better solution that will allow querying and inserting. The key is updating the map for TestChild to not insert records. The new map is:
public class TestChildMap : ClassMap<TestChild>
{
public TestChildMap()
{
Table("TestChild");
CompositeId()
.KeyProperty(x => x.ChildName, "ChildName")
.KeyReference(x => x.Parent, "TestParentId");
Map(x => x.Age);
References(x => x.Parent, "TestParentId")
.Not.Insert(); // will avoid "Index was out of range" error on insert
}
}
Any reason you can't modify your query to just be
_sessionBuilder.GetSession().CreateCriteria<TestChild>()
.Add(Restrictions.Eq("Parent.TestParentId", 1))
.List<TestChild>()
Then get rid of the reference?

HasMany cause KeyNotFoundException on Delete

hi i'm new to nhibernate and i read a lot of threads with similar problems, but i dont get it working.
i use oracle, nhibernate3 alpha and fluent nhibernate for mapping. i have a parent child relation. the child table has a composite id. Select, insert, update records works. Delete a parent without child records works. But deleting a parent with childs or just delete a child throws a KeyNotFoundException. it seems i miss something in my mapping?
StackTrace
bei System.Collections.Generic.Dictionary`2.get_Item(TKey key)
bei NHibernate.Engine.StatefulPersistenceContext.RemoveEntity(EntityKey key) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\StatefulPersistenceContext.cs:Zeile 434.
bei NHibernate.Action.EntityDeleteAction.Execute() in d:\CSharp\NH\nhibernate\src\NHibernate\Action\EntityDeleteAction.cs:Zeile 86.
bei NHibernate.Engine.ActionQueue.Execute(IExecutable executable) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:Zeile 130.
bei NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:Zeile 113.
bei NHibernate.Engine.ActionQueue.ExecuteActions() in d:\CSharp\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs:Zeile 151.
bei NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:Zeile 241.
bei NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) in d:\CSharp\NH\nhibernate\src\NHibernate\Event\Default\DefaultFlushEventListener.cs:Zeile 19.
bei NHibernate.Impl.SessionImpl.Flush() in d:\CSharp\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:Zeile 1524.
bei NHibernate.Transaction.AdoTransaction.Commit() in d:\CSharp\NH\nhibernate\src\NHibernate\Transaction\AdoTransaction.cs:Zeile 187.
bei LFF.Kabu.Win.Tabellenverwaltung.DataAccess.NHibernate.UnitOfWork.CommitTransaction() in C:\Demos\Tabellenverwaltung\DataAccess.NHibernate\UnitOfWork.cs:Zeile 77.
bei LFF.Kabu.Win.TabModul.DruckUndVersand.ViewModel.DruckUndVersandVM.SaveData()
below my entity classes and mappings:
public class DruckUndVersand
{
public DruckUndVersand()
{
this.RefFilters = new List<RefDruckUndVersandFilter>();
}
public virtual long Id { get; set; }
public virtual string Programm { get; set; }
public virtual string Variante { get; set; }
public virtual string Beschreibung { get; set; }
public virtual bool IsActive { get; set; }
public virtual IList<RefDruckUndVersandFilter> RefFilters { get; set; }
}
public class RefDruckUndVersandFilter
{
public virtual DruckUndVersand DruckUndVersand { get; set; }
public virtual long Rank { get; set; }
public virtual string Filter { get; set; }
#region override Equals(), GetHashCode()
//
#endregion
}
my fluent mappings look like this:
public class DruckUndVersandMapper : ClassMap<DruckUndVersand>
{
public DruckUndVersandMapper()
{
Table("Tab_DruckUndVersand");
Id(x => x.Id, "ID")
.GeneratedBy.Sequence("SEQ_DruckUndVersand");
Map(x => x.Programm).Not.Nullable().Length(255);
Map(x => x.Variante).Length(255);
Map(x => x.Beschreibung).Length(255);
Map(x => x.IsActive).Column("ISACTIVE").CustomType<YesNoType>().Length(1);
HasMany(x => x.RefFilters)
.KeyColumn("IDDruckUndVersand")
.NotFound.Ignore()
.Inverse()
.Cascade.All()
;
}
}
public class RefDruckUndVersandFilterMapper : ClassMap<RefDruckUndVersandFilter>
{
public RefDruckUndVersandFilterMapper()
{
Table("REFDruckUndVersandFILTER");
Not.LazyLoad();
Map(x => x.Filter);
CompositeId()
.KeyReference(x => x.DruckUndVersand, "IDDruckUndVersand")
.KeyProperty(x => x.Rank, "FILTERRANK");
}
}
i got it working now. the problem was my override for Equals() and GetHashCode().
public override bool Equals(object obj)
{
var toCompare = obj as RefDruckUndVersandFilter;
if (toCompare == null)
return false;
if (!GetType().Equals(toCompare.GetActualType()))
return false;
if (ReferenceEquals(this, toCompare))
return true;
return DruckUndVersand == toCompare.DruckUndVersand
&& Rank == toCompare.Rank
//&& Filter == toCompare.Filter //old causes the error
;
}
protected virtual Type GetActualType()
{
return GetType();
}
public override int GetHashCode()
{
unchecked
{
var hashcode = GetType().GetHashCode();
hashcode = (hashcode * 31) ^ (DruckUndVersand != null ? DruckUndVersand.GetHashCode() : 0);
hashcode = (hashcode * 31) ^ Rank.GetHashCode();
//hashcode = (hashcode * 31) ^ (Filter!= null ? Filter.GetHashCode() : 0); old
return hashcode;
}
}