Fluent NHibernate-级联所有删除孤立项在删除时不执行任何操作

Fluent NHibernate-级联所有删除孤立项在删除时不执行任何操作,nhibernate,fluent-nhibernate,nhibernate-mapping,fluent-nhibernate-mapping,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,Fluent Nhibernate Mapping,我有两个简单的类,它们作为一对多关系相互引用,定义如下: public class Project { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual IList<Document> Documents { get; set; } } public class Document { public virtual in

我有两个简单的类,它们作为一对多关系相互引用,定义如下:

public class Project
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Document> Documents { get; set; }
}

public class Document
{
    public virtual int Id { get; set; }
    public string FileName { get; set; }
}
将从数据库中删除正确的行。 但是,如果我要在带有HttpPost属性的操作中执行相同的操作,则永远不会删除该行


另外,我应该注意,如果我在带有HttpPost属性的操作中向project.Documents添加文档,repository.Update(project)会成功地将具有正确外键引用的行添加到项目中。这只是在我删除文档时失败。

您是否尝试将
.Inverse
添加到您的
映射中


另外,我不熟悉
not.KeyNullable
。我认为这里没有必要。层叠设置似乎是正确的。提到的问题可能在其他地方:

但是,如果要从与项目关联的文档列表中删除文档

我怀疑是会话刷新模式,或者缺少更新父实体
Project
的显式调用,该调用以前已分离。保证:

首先,调用了
Flush()
。如果
project
实例仍保持在会话中,则可以更改刷新的默认行为。(例如,
session.FlushMode=FlushMode.Never;
Commit
无事务…)

第二个可以被逐出
project
实例,需要显式的更新调用

// 2) updating evicted project instance
project.Documents.Remove(doc);
Session.Update(project);
//Session.Flush(); // Session session.FlushMode = FlushMode.Auto

在这种情况下,设置反向将(仅)有助于使用UPDATE语句减少一次数据库访问,将引用重置为
doc.Project=null
,然后执行DELETE。

我更新了我的问题,希望有更多有用的信息。我无法让你的任何建议发挥作用。您还有什么建议吗?作为一个问题,我在
HttpPost
中看到MVC运行时为您实例化新的项目实例,并将其与表单值绑定。我建议通过
Id
从NHibernate会话中获取一个实例,然后绑定它。你的情况可能吗?因为现在NHibernate提供了新的收藏,没有关于移除物品的信息…你有什么建议吗?如果我尝试
Project entity=repository.FindById(Project.Id);实体=项目;更新(实体)我收到错误:具有相同标识符值的另一个对象已与会话1关联,如果我从映射中删除
.Not.KeyNullable()
,则从项目中删除文档时,只需将外键“document\u project\u Id”更改为null并解除文档与项目的关联。这不是我想要的,我想要完全删除文档行。我是否在映射中遗漏了什么?语句
entiy=project将只更改实体引用的目标(到项目),而原始实例仍将在会话中。尝试绑定从会话
entity=FindById(id)接收的实体
更新模型(实体)
Repository.Udpate(实体)
public class SessionFactoryHelper
{
    public static ISessionFactory CreateSessionFactory()
    {
        var c = Fluently.Configure();
        try
        {
            //Replace connectionstring and default schema
            c.Database(OdbcConfiguration.MyDialect.
                ConnectionString(x =>
                x.FromConnectionStringWithKey("DBConnect"))
                .Driver<NHibernate.Driver.OdbcDriver>()
                .Dialect<NHibernate.Dialect.Oracle10gDialect>())
                .ExposeConfiguration(cfg => cfg.SetProperty("current_session_context_class", "web"));
            c.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Project>());
            c.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Document>());
        }
        catch (Exception ex)
        {
            Log.WriteLine(ex.ToString());
        }
        return c.BuildSessionFactory();
    }
}

public class MvcApplication : System.Web.HttpApplication
{
    public static ISessionFactory SessionFactory { get; private set; }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();

        SessionFactory = SessionFactoryHelper.CreateSessionFactory();
    }

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        var session = SessionFactory.OpenSession();
        CurrentSessionContext.Bind(session);
    }

    protected void Application_EndRequest(object sender, EventArgs e)
    {
        var session = CurrentSessionContext.Unbind(SessionFactory);
        session.Dispose();
    }
}
public class Repository<T> : IRepository<T>
{
    public virtual ISession Session
    {
        get { return MvcApplication.SessionFactory.GetCurrentSession(); }
    }

    public T FindById(int iId)
    {
        return Session.Get<T>(iId);
    }

    public void Save(T obj)
    {
        using (var transaction = Session.BeginTransaction())
        {
            try
            {
                Session.Save(obj);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();

                Log.WriteLine(ex.ToString());
            }
        }
    }

    public T SaveOrUpdate(T obj)
    {
        using (var transaction = Session.BeginTransaction())
        {
            try
            {
                Session.SaveOrUpdate(obj);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();

                Log.WriteLine(ex.ToString());
            }
        }

        return obj;
    }

    public T Update(T obj)
    {
        using (var transaction = Session.BeginTransaction())
        {
            try
            {
                Session.Update(obj);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();

                Log.WriteLine(ex.ToString());
            }
        }

        return obj;
    }
}
private IRepository<Project> repository;

public ProjectsController()
{
    repository = new Repository<Project>();
}

public ActionResult Edit(int iId)
{
    Project project = repository.FindById(iId);

    if (project == null)
        return HttpNotFound();

    return View(project);
}

[HttpPost]
public ActionResult Edit(Project project)
{
    project = repository.Update(project);

    return View(project);
}
project.Documents.RemoveAt(0);
repository.Update(project);
// 1) checking the explicit Flush()
project.Documents.Remove(doc);
Session.Flush(); // this will delete that orphan
// 2) updating evicted project instance
project.Documents.Remove(doc);
Session.Update(project);
//Session.Flush(); // Session session.FlushMode = FlushMode.Auto