【问题标题】:Entity Framework many-to-many relationship in a html tablehtml表中的实体框架多对多关系
【发布时间】:2021-06-16 08:40:52
【问题描述】:

我正在 .net core 3.1 中创建一个 ASP.NET 项目,其中包含通过第三个表(用户地址)具有 NxN 关系的 2 个表(用户和地址)

public class User
{
    public Guid ID { get; set; }
    [Required]
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
    public string Description { get; set; }
    public List<UserAddress> Addresses { get; set; }
}

public class Address
{
    public Guid ID { get; set; }
    [Required]
    public string Information { get; set; }
    public bool IsCommercial { get; set; }
    public List<UserAddress> Users { get; set; }
}

public class UserAddress
{
    public Guid UserID { get; set; }
    public Guid AddressID { get; set; }
    public User User { get; set; }
    public Address Address { get; set; }
}

public class ManagerContext : DbContext
{
    public ManagerContext(DbContextOptions<ManagerContext> options) : base(options)
    {
    }

    public DbSet<User> User { get; set; }
    public DbSet<Address> Address { get; set; }
    public DbSet<UserAddress> UserAddress { get; set; }
    public DbSet<Department> Department { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .HasIndex(e => new { e.Name })
            .IsUnique(true);

        modelBuilder.Entity<Address>()
            .HasIndex(e => new { e.Information })
            .IsUnique(true);

        modelBuilder.Entity<UserAddress>()
            .HasKey(e => new { e.UserID, e.AddressID });

        modelBuilder.Entity<Department>()
            .HasIndex(e => new { e.Name })
            .IsUnique(true);
    }
}

我想创建一个 HTML 页面,显示特定用户的详细信息以及与该用户相关的地址列表

<div>
    <h4>User</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Name)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Name)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Age)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Age)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Email)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Email)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Description)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Description)
        </dd>
    </dl>

    <table class="table table-striped">
        <thead>
            <tr>
                <th scope="col">#</th>
                <th scope="col">@Html.DisplayNameFor(model => model.Addresses[0].Address.Information)</th>
                <th scope="col">@Html.DisplayNameFor(model => model.Addresses[0].Address.IsCommercial)</th>
            </tr>
        </thead>
        <tbody>
            @for (int i = 0; i < Model.Addresses.Count; i++)
            {
                <tr>
                    <th scope="col">@i</th>
                    <td>@Html.DisplayFor(model => model.Addresses[i].Address.Information)</td>
                    <td>@Html.DisplayFor(model => model.Addresses[i].Address.IsCommercial)</td>
                </tr>
            }
        </tbody>
    </table>
</div>

但是,由于某种原因,User.Addresses 列表为空并返回错误,因为代码尝试获取空对象的 Count 属性。为什么该列表没有填充 UserAddress 列表?我做错了什么?

【问题讨论】:

  • 你能显示加载数据的查询吗?你用过IncludeThenInclude吗?另外 - 我可以看到您在连接表 UserAddress 中创建了连接的主键。为其他组合创建索引是一种很好的做法 - 所以 HasIndex(e =&gt; new { e.AddressID, e.UserID }); 出于性能查找原因。
  • Include 和 ThenInclude 是什么意思?我用 HasIndex(e => new { e.AddressID, e.UserID });但它也不起作用(感谢您的提示)。
  • 天哪,我使用了 Include,它起作用了。谢谢!!

标签: c# asp.net .net asp.net-mvc entity-framework


【解决方案1】:

public class User
{
    public Guid ID { get; set; }
    [Required]
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
    public string Description { get; set; }
    public List<Address> Addresses { get; set; }
}

public class Address
{
    public Guid ID { get; set; }
    [Required]
    public string Information { get; set; }
    public bool IsCommercial { get; set; }
    public List<User> Users { get; set; }
}

public class UserAddress
{
    public Guid ID { get; set; }
    public Guid UserId { get; set; }
    public Guid AddressId { get; set; }
    public DateTime CreatedAt { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<User>()
        .HasMany(user => user.Addresses)
        .WithMany(address => address.Users)
        .UsingEntity<UserAddress>
        (pt => pt.HasOne<Address>().WithMany(),
            pt => pt.HasOne<User>().WithMany())
        .Property(pt => pt.CreatedAt)
        .HasColumnType("timestamp without time zone")
        .HasDefaultValueSql("NOW()")
        .ValueGeneratedOnAdd();
}

【讨论】:

  • 请解释你的代码是做什么的以及它是怎么做的。
  • 对于两个实体之间的多对多关系,无需使用第三个实体。使用第三个实体添加有效负载,即 createdAt,正如我在代码中提到的那样。
猜你喜欢
  • 1970-01-01
  • 2017-01-28
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多