【问题标题】:Having an Issue creating a one to many relation using Entity framework使用实体框架创建一对多关系时遇到问题
【发布时间】:2014-05-16 22:48:37
【问题描述】:

我已经看到很多关于这个问题的问题,但我找不到对我有帮助的问题,我试图在建筑物和房间之间建立一对多的关系,即一栋有很多房间的建筑物。据我所知,我的 ICollection 值没有发送到我的数据库。我正在使用局部视图在建筑物内创建房间,我的建筑物模型包含 Icollection,我的房间模型包含建筑物 ID。但是,当我创建一个房间时,它不会将 buildingId 与 ICollection 值连接起来。

这是我的建筑和房间模型:

public class buildingInfo
{
    public int Id { get; set; }
    public int buildingNumber { get; set; }
    public String buildingName { get; set; }
    public String buildingAddress { get; set; }
    public String buildingDesc { get; set; }
    public virtual ICollection<roomInfo> curRooms { get; set; }
}

public class roomInfo
{
    public int Id { get; set; }
    public int roomNumber { get; set; }
    public String roomName { get; set; }
    public String roomLocation { get; set; }
    public String roomDesc { get; set; }
    public int buildingId { get; set; }
}

这是房间视图:

 @model TerminalHost.Models.buildingInfo

@{
ViewBag.Title = "Home Page";
}
<h3>Rooms in: @Model.buildingName</h3>
<ol class="round">

<li class="one">
    <h5>Please begin creating your network structure:</h5> <button id="modal-opener">Add a new room</button>

</li>
</ol>

@Html.Partial("rooms", Model.curRooms)

<div id="Modal" title="Room Details">
    @Html.Partial("roomForm", new TerminalHost.Models.roomInfo { buildingId =  Model.Id })
</div>

这是包含房间详细信息的表格:

@model TerminalHost.Models.roomInfo

 <h2>Create</h2>

 @using (Html.BeginForm("roomForm","Home"))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

<fieldset>
    <legend>roomInfo</legend>

    <div class="editor-label">
        @Html.Label("Room Number:")
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.roomNumber)
        @Html.ValidationMessageFor(model => model.roomNumber)
    </div>
    ....
    <div style="visibility: hidden">

        <div class="editor-field">
            @Html.TextBoxFor(model => model.buildingId)
            @Html.ValidationMessageFor(model => model.buildingId)
        </div>
    </div>
    <p>
        <input type="submit" value="Create" />
    </p>
 </fieldset>
 }
 @section Scripts {
   @Scripts.Render("~/bundles/jqueryval")
 }

这些是处理房间局部视图的方法:

 [HttpGet]
    public ActionResult roomForm(int buildingId)
    {
        return PartialView();
    }
    //Here the data from the room form is inserted to the database
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult roomForm(roomInfo roominfo)
    {
        //roominfo.
        if (ModelState.IsValid)
        {
            _db.rooms.Add(roominfo);
            _db.SaveChanges();
            return RedirectToAction("room", new {id = roominfo.buildingId});
        }

        return PartialView(roominfo);
    }

这是 DBContext:

public class thDB : DbContext
{
    public DbSet<buildingInfo> buildings { get; set; }
    public DbSet<roomInfo> rooms { get; set; }
    public DbSet<deviceInfo> devices { get; set; }
    public DbSet<rackInfo> rackInfoes { get; set; }
} 

如果需要任何进一步的信息,请询问。

【问题讨论】:

  • 您的 buildinginfo 类应该有一个构造函数来初始化 roomInfo 列表。 curRooms = 新列表();
  • 像这样:public List curRooms = new List();

标签: asp.net-mvc database entity-framework partial-views one-to-many


【解决方案1】:

我认为 Entity Framework 无法通过其约定识别实体之间的正确外键,因为您的属性命名约定与 EF 期望的任何内容都不匹配。它可能会添加自己的外键,因此当您在 roomInfo 实体上设置 buildingId 时,它不会被视为外键。

您可以尝试在 DbContext 中添加一些实体映射配置来明确描述关系:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<buildingInfo>().HasMany(b=>b.curRooms).WithRequired().HasForeignKey(r=>r.buildingId);
}

【讨论】:

  • 我在实现你的代码时遇到了这个错误:方法'System.Data.Entity.ModelConfiguration.Configuration.DependentNavigationPropertyConfiguration.HasForeignKey( System.Linq.Expressions.Expression>)' 无法从用法中推断出来。尝试明确指定类型参数。
  • 这就是我在网页文本字段中编写代码所得到的。 ;) 检查上面答案中的更新代码。
  • 成功了!我已经坚持了好几天了。我可以为房间内的机架一对多地复制这个吗?
  • 是的,你可以。在我看来,编写上述代码来明确描述实体之间的每一种关系而不是试图依赖约定是个好主意。
【解决方案2】:

希望对你有帮助

public class buildingInfo
{

    public buildingInfo()
    {
        curRooms = new List<roomInfo>();

    }

    [Key]
    public int Id { get; set; }

    public int buildingNumber { get; set; }
    public String buildingName { get; set; }
    public String buildingAddress { get; set; }
    public String buildingDesc { get; set; }

    public virtual ICollection<roomInfo> curRooms { get; set; }
}

public class roomInfo
{

    public roomInfo()
    {
    }

    [Key]
    public int Id { get; set; }

    public int roomNumber { get; set; }
    public String roomName { get; set; }
    public String roomLocation { get; set; }
    public String roomDesc { get; set; }

    public virtual buildingInfo BuildingInfo { get; set; }
}

【讨论】:

  • 我输入了代码并尝试更新包管理器,但它给了我这个反馈:类型“TerminalHost.Models.roomInfo”的属性“buildingId”上的 ForeignKeyAttribute 无效。在依赖类型“TerminalHost.Models.roomInfo”上找不到导航属性“buildingInfo”。 Name 值应该是有效的导航属性名称。
  • 当我真的不需要时,我明确设置了外键。见更新。我已经测试过了,它工作正常
猜你喜欢
  • 2017-04-11
  • 2017-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
相关资源
最近更新 更多