【问题标题】:Controller saves referenced instances as new instances instead of updating the existing ones控制器将引用的实例保存为新实例,而不是更新现有的实例
【发布时间】:2011-03-01 16:44:20
【问题描述】:

我搜索并发现以下链接 link alink b 没有解释我做错了什么。

我在自动映射模式下使用 MVC3 + Fluent + NHibernate 和 Fluent,配置如下:

NHibernate.Cfg.Configuration().Configure();
XXConfiguration autoMappingConf = new XXConfiguration();
FluentConfiguration fc = Fluently.Configure()
     .Database(MsSqlConfiguration.MsSql2008.ConnectionString(
         ConfigurationManager.ConnectionStrings[myConnString].ConnectionString
      )
      .ShowSql());
fc.ExposeConfiguration(cfg =>      cfg.SetProperty(NHibernate.Cfg.Environment.CurrentSessionContextClass, "web"));
fc.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<BasicEntity>(autoMappingConf)
                .UseOverridesFromAssemblyOf<AccountMappingOverride>()
                .Conventions.Add(DefaultCascade.All()))
                );
        return fc.BuildSessionFactory();
    }

并具有以下覆盖:

public class AccountMappingOverride: IAutoMappingOverride<Account>
{
    public void Override(AutoMapping<Account> mapping)
    {
        mapping.HasMany(a => a.ChildrenAccounts).KeyColumn("ParentAccount_id");
    }
}

我有以下型号:

public abstract class Entity<TId>
{
    public virtual TId Id { get; set; }
    public virtual int ExternalId { get; set; }
}

public abstract class BasicEntity : Entity<int>{}

public abstract class MainEntity : BasicEntity
{
    public virtual int Version { get; set; }
    public virtual bool Active { get; set; }
}

public class Language : MainEntity 
{
    public virtual string Code { get; set; }
    public virtual string Name { get; set; }
}

public class Account : MainEntity
{
    public virtual string Name { get; set; }
    public virtual Language Language { get; set; }
    public virtual Account ParentAccount { get; set; }
    public virtual IList<Account> ChildrenAccounts { get; set; }
    public virtual IList<User> Users { get; set; }

}

 public class User : MainEntity
{
    public virtual string Name { get; set; }
    public virtual string Surname { get; set; }
    public virtual string Email { get; set; }
    [DataType(DataType.Password)]
    public virtual string Password { get; private set; }
    public virtual Language Language { get; set; }
    public virtual Account Account { get; set; }
    public virtual DateTime? LastLoginDate { get; set; }
    public virtual DateTime? LastPasswordChangeDate { get; set; }
}

还有一个显示创建新帐户的字段的视图:

@model XX.Models.Account

@{
   ViewBag.Title = "New Account";
   Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>New account</h2>

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)

    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name)
    </div>


    <div class="editor-label">
        @Html.LabelFor(model => model.ParentAccount)
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(model => model.ParentAccount.Id, XX.Utils.SelectList<XX.Models.Account>("Name", (string)ViewBag.parentAccountId))
        @Html.ValidationMessageFor(model => model.ParentAccount)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Language)
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(model => model.Language.Id,  XX.Utils.SelectList<XX.Models.Language>("Name", ""))
        @Html.ValidationMessageFor(model => model.Language)
    </div>

    <p>
        <input type="submit" value="Add" />
    </p>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

控制器保存,但不是简单地分配字段语言,而是在保存过程中创建一种新语言,而不是更新现有语言。检查传递给控制器​​的 Account 对象,我们注意到它引用了具有已经存在 id 的 Language 对象。这适用于任何参考映射。

 [HttpPost]
 [NeedsPersistence]
 public ActionResult Create(Account account)
    {
        if (ModelState.IsValid)
        {
            accountDao.Save(account, currentUser);
            return RedirectToAction("Tree");
        }
        else {
            return View();
        }
    }

如何获得保存以识别语言已经存在?

【问题讨论】:

    标签: hibernate asp.net-mvc-3 fluent


    【解决方案1】:

    看到这一行:

    @Html.DropDownListFor(model => model.Language.Id, XX.Utils.SelectList("Name", ""))

    您正在告诉显示字段是什么,但数据字段是一个空字符串。

    我猜应该是这样的:

    @Html.DropDownListFor(model => model.Language.Id, XX.Utils.SelectList("Name", "Id"))

    【讨论】:

      【解决方案2】:

      我们通过定义 ViewModels 解决了这个问题(我们将 Language 属性排除在外,因为它已从模型中删除,但同样的情况适用于 ParentAccount)和控制器如下:

      public class AccountEdit
      {
          public int Id { get; set; }
          [Required]
          [LocalizedDisplayName("Name")]
          public string Name { get; set; }
          [LocalizedDisplayName("ParentAccount")]
          public int ParentAccount { get; set; }
          [LocalizedDisplayName("Role")]
          public Role Role { get; set; }
      
          public AccountEdit() { }
      
          public AccountEdit(Account a)
          {
              Id = a.Id;
              Name = a.Name;
              ParentAccount = a.ParentAccount!=null ? a.ParentAccount.Id : 0;
              Role = a.Role;
          }
      
          public Account BoundAccount()
          {
              DataAccessObject<Account> dao = new DataAccessObject<Account>();
              Account account = dao.Get(Id);
              account.Name = Name;
              if (ParentAccount == default(int))
                  account.ParentAccount = null;
              else
                  account.ParentAccount = dao.Get(ParentAccount);
              return account;
          }
      }
      
          [HttpPost]
          [NeedsPersistence]
          public ActionResult CreateDistributor(DistributorCreate dc)
          {
              if (ModelState.IsValid)
              {
                  Account account = dc.BoundAccount();
                  accountDao.Save(account, currentUser);
                  return RedirectToAction("Index");
              }
              else {
                  return View(dc);
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多