Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I have ended up doing my own DuplicateEntityChecker and have changed ComponentRegistrar to use that instead of SharpArch one.</p> <p>My class looks like this.</p> <pre><code>using NHibernate; using SharpArch.Core.DomainModel; using System.Reflection; using System; using NHibernate.Criterion; using SharpArch.Core; using SharpArch.Core.PersistenceSupport; using System.Linq; using SharpArch.Data.NHibernate; namespace your.namespace.Data.NHibernate { public class EntityDuplicateChecker : IEntityDuplicateChecker { /// &lt;summary&gt; /// Provides a behavior specific repository for checking if a duplicate exists of an existing entity. /// &lt;/summary&gt; public bool DoesDuplicateExistWithTypedIdOf&lt;IdT&gt;(IEntityWithTypedId&lt;IdT&gt; entity) { Check.Require(entity != null, "Entity may not be null when checking for duplicates"); ISession session = GetSessionFor(entity); FlushMode previousFlushMode = session.FlushMode; // We do NOT want this to flush pending changes as checking for a duplicate should // only compare the object against data that's already in the database session.FlushMode = FlushMode.Never; Criteria = session.CreateCriteria(entity.GetType()) .Add(Expression.Not(Expression.Eq("Id", entity.Id))) .SetMaxResults(1); AppendSignaturePropertyCriteriaTo&lt;IdT&gt;(Criteria, entity); bool doesDuplicateExist = Criteria.List().Count &gt; 0; session.FlushMode = previousFlushMode; return doesDuplicateExist; } public ICriteria Criteria { get; protected set; } private void AppendSignaturePropertyCriteriaTo&lt;IdT&gt;(ICriteria criteria, IEntityWithTypedId&lt;IdT&gt; entity) { foreach (PropertyInfo signatureProperty in entity.GetSignatureProperties()) { Type propertyType = signatureProperty.PropertyType; object propertyValue = signatureProperty.GetValue(entity, null); if (propertyType.IsEnum) { criteria.Add( Expression.Eq(ResolvePropertyName(string.Empty, signatureProperty), (int)propertyValue)); } else if (propertyType.GetInterfaces() .Any(x =&gt; x.IsGenericType &amp;&amp; x.GetGenericTypeDefinition() == typeof(IEntityWithTypedId&lt;&gt;))) { AppendEntityCriteriaTo&lt;IdT&gt;(criteria, signatureProperty, propertyValue); } else if (propertyType == typeof(DateTime)) { AppendDateTimePropertyCriteriaTo(criteria, string.Empty, signatureProperty, propertyValue); } else if (propertyType == typeof(String)) { AppendStringPropertyCriteriaTo(criteria, string.Empty, signatureProperty, propertyValue); } else if (propertyType.IsValueType) { AppendValuePropertyCriteriaTo(criteria, string.Empty, signatureProperty, propertyValue); } else if(typeof(ValueObject).IsAssignableFrom(propertyType)) { AppendValueObjectSignaturePropertyCriteriaTo(criteria, signatureProperty.Name + ".", propertyValue as ValueObject); } else { throw new ApplicationException("Can't determine how to use " + entity.GetType() + "." + signatureProperty.Name + " when looking for duplicate entries. To remedy this, " + "you can create a custom validator or report an issue to the S#arp Architecture " + "project, detailing the type that you'd like to be accommodated."); } } } private void AppendValueObjectSignaturePropertyCriteriaTo(ICriteria criteria, string parentPropertyName, ValueObject valueObject) { if(valueObject == null) return; foreach (PropertyInfo signatureProperty in valueObject.GetSignatureProperties()) { Type propertyType = signatureProperty.PropertyType; object propertyValue = signatureProperty.GetValue(valueObject, null); if (propertyType.IsEnum) { criteria.Add( Expression.Eq(ResolvePropertyName(parentPropertyName, signatureProperty), (int)propertyValue)); } else if (propertyType == typeof(DateTime)) { AppendDateTimePropertyCriteriaTo(criteria, parentPropertyName, signatureProperty, propertyValue); } else if (propertyType == typeof(String)) { AppendStringPropertyCriteriaTo(criteria, parentPropertyName, signatureProperty, propertyValue); } else if (propertyType.IsValueType) { AppendValuePropertyCriteriaTo(criteria, parentPropertyName, signatureProperty, propertyValue); } else if (typeof(ValueObject).IsAssignableFrom(propertyType)) { AppendValueObjectSignaturePropertyCriteriaTo(criteria, ResolvePropertyName(parentPropertyName, signatureProperty), propertyValue as ValueObject); } else { throw new ApplicationException("Can't determine how to use " + valueObject.GetType() + "." + signatureProperty.Name + " when looking for duplicate entries. To remedy this, " + "you can create a custom validator or report an issue to the S#arp Architecture " + "project, detailing the type that you'd like to be accommodated."); } } } private void AppendStringPropertyCriteriaTo(ICriteria criteria, string parentPropertyName, PropertyInfo signatureProperty, object propertyValue) { var propertyName = ResolvePropertyName(parentPropertyName, signatureProperty); if (propertyValue != null) { criteria.Add( Expression.InsensitiveLike(propertyName, propertyValue.ToString(), MatchMode.Exact)); } else { criteria.Add(Expression.IsNull(propertyName)); } } private void AppendDateTimePropertyCriteriaTo(ICriteria criteria, string parentPropertyName, PropertyInfo signatureProperty, object propertyValue) { var propertyName = ResolvePropertyName(parentPropertyName, signatureProperty); if ((DateTime) propertyValue &gt; UNINITIALIZED_DATETIME) { criteria.Add(Expression.Eq(propertyName, propertyValue)); } else { criteria.Add(Expression.IsNull(propertyName)); } } private void AppendValuePropertyCriteriaTo(ICriteria criteria, string parentPropertyName, PropertyInfo signatureProperty, object propertyValue) { var propertyName = ResolvePropertyName(parentPropertyName, signatureProperty); if (propertyValue != null) { criteria.Add(Expression.Eq(propertyName, propertyValue)); } else { criteria.Add(Expression.IsNull(propertyName)); } } private static void AppendEntityCriteriaTo&lt;IdT&gt;(ICriteria criteria, PropertyInfo signatureProperty, object propertyValue) { if (propertyValue != null) { criteria.Add(Expression.Eq(signatureProperty.Name + ".Id", ((IEntityWithTypedId&lt;IdT&gt;)propertyValue).Id)); } else { criteria.Add(Expression.IsNull(signatureProperty.Name + ".Id")); } } private static string ResolvePropertyName(string parentPropertyName, PropertyInfo signatureProperty) { if (string.IsNullOrEmpty(parentPropertyName)) return signatureProperty.Name; if (parentPropertyName.EndsWith(".") == false) parentPropertyName += "."; return string.Format("{0}{1}", parentPropertyName, signatureProperty.Name); } private static ISession GetSessionFor(object entity) { var factoryKey = SessionFactoryAttribute.GetKeyFrom(entity); return NHibernateSession.CurrentFor(factoryKey); } private readonly DateTime UNINITIALIZED_DATETIME = default(DateTime); } } </code></pre> <p>Hope this helps anyone with the same problem.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload