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