2015-04-03 78 views
0

我在我的遷移中定義了我的表中唯一的一列。如果我嘗試保存違反當然這種唯一性約束的記錄,我收到一個異常:果園1.8 - 用獨特的字段保存記錄

A duplicate value cannot be inserted into a unique index. 

保存記錄我使用的IRepository創建和更新方法,因爲它不具備相當的部分。在收到上面的異常後,我會捕獲它,然後啓動AddModelError以停止保存過程。 Neverthless果園給了我另一個異常後:

[AssertionFailure: null id in MyModule.Models.MyRecord entry (don't flush the Session after an exception occurs)] 
    NHibernate.Event.Default.DefaultFlushEntityEventListener.CheckId(Object obj, IEntityPersister persister, Object id, EntityMode entityMode) +267 
    NHibernate.Event.Default.DefaultFlushEntityEventListener.GetValues(Object entity, EntityEntry entry, EntityMode entityMode, Boolean mightBeDirty, ISessionImplementor session) +95 
    NHibernate.Event.Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent event) +139 
    NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent event) +448 
    NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event) +283 
    NHibernate.Event.Default.DefaultAutoFlushEventListener.OnAutoFlush(AutoFlushEvent event) +84 
    NHibernate.Impl.SessionImpl.AutoFlushIfRequired(ISet`1 querySpaces) +471 
    NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results) +477 
    NHibernate.Impl.AbstractSessionImpl.List(IQueryExpression queryExpression, QueryParameters parameters) +223 
    NHibernate.Impl.ExpressionQueryImpl.List() +189 
    NHibernate.Linq.DefaultQueryProvider.ExecuteQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery) +61 
    NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression) +262 
    NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression) +26 
    Remotion.Linq.QueryableBase`1.GetEnumerator() +83 
    System.Linq.Enumerable.ToDictionary(IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer) +173 
    System.Linq.Enumerable.ToDictionary(IEnumerable`1 source, Func`2 keySelector) +125 
    Orchard.Data.Migration.DataMigrationManager.GetFeaturesThatNeedUpdate() +311 
    Orchard.Modules.Data.Migration.<GetNotifications>d__6.MoveNext() +219 
    System.Linq.<SelectManyIterator>d__14`2.MoveNext() +507 
    System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +536 
    System.Linq.Enumerable.ToList(IEnumerable`1 source) +80 
    Orchard.UI.Admin.Notification.NotificationManager.GetNotifications() +151 
    Orchard.UI.Admin.Notification.AdminNotificationFilter.OnResultExecuting(ResultExecutingContext filterContext) +380 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +245 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +890 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +890 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +890 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +890 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +97 
    System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +241 
    System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29 
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +111 
    System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53 
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +19 
    System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +51 
    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +111 
    Orchard.Mvc.Routes.HttpAsyncHandler.EndProcessRequest(IAsyncResult result) +95 
    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +606 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288 

如果我理解正確的是什麼原因造成,果園自動嘗試將記錄刷新到數據庫中,即使我添加了一個模型誤差。我試圖改變事務範圍,但它不起作用。有沒有辦法解決這個問題?

+0

不知道你是否可以使用庫來做到這一點,但通常你會做'_transactionManager.Cancel()' – devqon 2015-04-03 13:49:47

+0

不幸的是,它不起作用。我已經嘗試過,並收到相同的錯誤。 – Soel 2015-04-03 14:20:00

回答

2

在處理內容部分記錄時,不能使用Unique約束。原因是那些數據是很早創建的,當時還沒有數據傳遞給它(所有的屬性都是空的或空的)。這發生在ContentManager之內。因此,這些記錄類型的所有屬性都必須是可以爲空且不唯一的。

但是,您可以對映射到您通過IRepository直接創建和使用的記錄的類使用唯一/非空約束。

0

如果這是針對ContentPart的,並且您有一種在.NET中爲您的字段創建唯一值的方法,那麼您始終可以在ContentHandler中爲您的部件使用OnInitializing事件。只要

public class ProductPartHandler: ContentHandler 
{ 
    public ProductPartHandler(IRepository<ProductPartRecord> repository) 
    { 
     Filters.Add(StorageFilter.For(repository)); 
     OnInitializing<ProductPart>((context, part) => 
     { 
      part.Sku = Guid.NewGuid().ToString(); 
     }); 
    } 
} 

,你可以產生某種您現場支持,那麼你可以隨時將其設置在保證獨特的價值:

例如,這適用於一個獨特的SKU場的分貝處理器處理獨特的約束,然後用你想要的真實值進行更新。