创建后实体不保留

时间:2019-06-04 14:29:42

标签: c# sqlite nhibernate

免责声明:这是我使用NHibernate的第一个项目,我可能会错过一些“显而易见的”内容。

我的问题如下。我有一个创建订单的命令:

public void Handle(BuyOneProductCommand command)
{
    var product = _uow.Query<Product>().Single(p => p.Name == command.ProductName);
    var order = new Order(product, 1);
    _uow.SaveOrUpdate(order);
    _uow.Commit();
}

该命令将接收新创建的UnitOfWork。但是,在Commit()之后,我的更改将永不持久化到数据库,也不会引发任何异常。有什么想法吗?

订购

public class Order : AggregateRoot
{
    public virtual Product Product { get; }
    public virtual int Quantity { get; }
    public virtual DateTime Date { get; }

    public Order(Product product, int quantity) : this()
    {
        Product = product;
        Quantity = quantity;
        Date = DateTime.Now;
        AddDomainEvent(new OrderCreatedEvent(this));
    }

    protected Order() { }
}

OrderMap

public class OrderMap : ClassMap<Order>
{
    public OrderMap()
    {
        Id(x => x.Id);
        References(o => o.Product);
        Map(x => x.Quantity);
        Map(x => x.Date);
    }
}

UnitOfWork

public sealed class UnitOfWork : IUnitOfWork
{
    private readonly ISession _session;
    private readonly ITransaction _transaction;
    private bool _isAlive = true;

    public UnitOfWork()
    {
        _session = SessionFactory.OpenSession();
        _transaction = _session.BeginTransaction(IsolationLevel.ReadCommitted);
    }

    public void Commit()
    {
        if (!_isAlive)
            return;

        try
        {
            _transaction.Commit();
        }
        finally
        {
            _isAlive = false;
            _transaction.Dispose();
            _session.Dispose();
        }
    }

    public T Get<T>(long id) where T : class
    {
        return _session.Get<T>(id);
    }

    public void SaveOrUpdate<T>(T entity)
    {
        _session.SaveOrUpdate(entity);
    }

    public IQueryable<T> Query<T>()
    {
        return _session.Query<T>();
    }
}

SessionFactory

public static class SessionFactory
{
    private static ISessionFactory _factory;

    public static void Init(string connectionString)
    {
        _factory = BuildSessionFactory(connectionString);
    }

    public static ISession OpenSession()
    {
        return _factory.OpenSession();
    }

    private static ISessionFactory BuildSessionFactory(string connectionString)
    {
        return Fluently.Configure()
            .Database(SQLiteConfiguration.Standard.ConnectionString(connectionString).ShowSql())
            .Mappings(m => m.FluentMappings
                .AddFromAssembly(Assembly.GetExecutingAssembly())
                .Conventions.Add(
                    ForeignKey.EndsWith("Id"),
                    ConventionBuilder.Property.When(criteria => criteria.Expect(x => x.Nullable, Is.Not.Set), x => x.Not.Nullable()))
                .Conventions.Add<OtherConventions>()
                .Conventions.Add<IncrementConvention>()
            )
            .ExposeConfiguration(x =>
            {
                x.EventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] { new DomainEventsListener() };
                x.EventListeners.PreInsertEventListeners = new IPreInsertEventListener[] { new DomainEventsListener() };
                x.EventListeners.PreDeleteEventListeners = new IPreDeleteEventListener[] { new DomainEventsListener() };
                x.EventListeners.PreCollectionUpdateEventListeners = new IPreCollectionUpdateEventListener[] { new DomainEventsListener() };
                x.EventListeners.PostCommitUpdateEventListeners = new IPostUpdateEventListener[] { new IntegrationEventsListener() };
                x.EventListeners.PostCommitInsertEventListeners = new IPostInsertEventListener[] { new IntegrationEventsListener() };
                x.EventListeners.PostCommitDeleteEventListeners = new IPostDeleteEventListener[] { new IntegrationEventsListener() };
                x.EventListeners.PostCollectionUpdateEventListeners = new IPostCollectionUpdateEventListener[] { new IntegrationEventsListener() };
                new SchemaUpdate(x).Execute(true, true);
            })
            .BuildSessionFactory();
    }

    private class OtherConventions : IHasManyConvention, IReferenceConvention
    {
        public void Apply(IOneToManyCollectionInstance instance)
        {
            instance.LazyLoad();
            instance.AsBag();
            instance.Cascade.SaveUpdate();
            instance.Inverse();
        }

        public void Apply(IManyToOneInstance instance)
        {
            instance.LazyLoad(Laziness.Proxy);
            instance.Cascade.None();
            instance.Not.Nullable();
        }
    }

    private class IncrementConvention : IIdConvention
    {
        public void Apply(IIdentityInstance instance)
        {
            instance.Column("Id");
            instance.GeneratedBy.Increment();
        }
    }
}

IPreInsertEventListener

public bool OnPreInsert(PreInsertEvent @event)
{
    var aggregateRoot = @event.Entity as AggregateRoot;
    if (aggregateRoot == null)
        return true;

    foreach (IEvent domainEvent in aggregateRoot.DomainEvents)
    {
        DomainEvents.Dispatch(domainEvent);
    }

    aggregateRoot.ClearDomainEvents();

    return true;
}

1 个答案:

答案 0 :(得分:0)

正如罗马人Artiukhin指出的那样,我的IPreInsertEventListener总是通过退回true来不断否决插入内容。

棘手的是,我认为此侦听器的返回值表示成功/失败,而表示否决 >。

因此,我不得不更改为始终返回false,这意味着否决权