使用包含相同 Entity MVC Core 的 1Entity 创建 Dbo

Make Dbo wtih 1Entity containing the same Entity MVC Core

我在编程方面相当陌生(6 个月)并且被 EF 踢了屁股,所以欢迎任何正确方向的指示! 我的 project/exercise 的目的是为狗主人和他们的狗制作一个 facebook 类型的应用程序。

特别是我正在努力与 Dogs 和他们的 DogFriends 一起制作 DBO。 目标是在表单中输入 Dogname,获取该名称的 DogId,并将其添加到包含 Dogs 及其 DogFriends 的 DBO。

我不太确定该怎么做。我正在考虑创建一个仅包含 DogId 列和 DogFriendId 列的 DBO(但我可能错了,因为看来我对 EFCore 的理解仍然非常有限^^)

我希望我包含了我所面临问题的所有必要代码,如果没有,请随时索取更多

     public class Dog : EntityBase<int>
{        
    public string FirstName { get; set; }
    public DogFertility DogFertility { get; set; }
    public DogGender DogGender { get; set; }
    public string Description { get; set; }
    public DateTime DoB { get; set; }      
    public DogBreed DogBreed { get; set; }        

    public virtual List<UserDog> UserDogs { get; set; }
    public virtual List<DogFriend> DogFriends{ get; set; }
    public virtual List<Dog> DogFriendList { get; set; }

    public Dog()
    {
        UserDogs = new List<UserDog>();
        DogFriends = new List<DogFriend>();
        DogFriendList = new List<Dog>();
    }             
}



    public class DogFriend : EntityBase<int>
{
    public string DogFriendSearchInput { get; set; }
    public string DogFriendFirstName { get; set; }        
    public Dog Dog { get; set; }    

    public DogFriend()
    {      
         DogFriendFirstName = DogFriendSearchInput;
    }
}

我得到了一个用于添加 DogFriends 的 ViewModel

     public class AddDogFriendViewModel
{
    public string DogFriendSearchInput { get; set; }
    public string DogFriendFirstName { get; set; }
    public int DogFriendId { get; set; }
    public DogBreed DogBreed { get; set; }
    public int DogId { get; set; }
    public string ReturnUrl { get; set; }       
    public DogFriend DogFriend { get; set; }
    public Domain.Model.Dog Dog { get; set; }

    public AddDogFriendViewModel()
    {
        DogFriendFirstName = DogFriendSearchInput;
    }
}

以及添加 DogFriends 的表格

     <div>
    <form method="post" asp-controller="DogOwner" asp-action="AddDogFriend" asp-route-returnurl="@Model.ReturnUrl">
        <div asp-validation-summary="ModelOnly"></div>
        <div class="navbar-header">
            <div class="navbar-collapse collapse" style="margin-left:-15px">
                <div>
                    <ul class="nav navbar-nav">
                        <div>
                           <li>                                    
                                <input asp-for="@Model.DogFriendSearchInput" value="@Model.AddDogFriendViewModel.DogFriendSearchInput" asp-route-dogFriendFirstName="DogFriendSearchInput" style="width:400px" type="text" id="DogFriendSearchInput" onkeyup="SearchDogFriends()" placeholder="Search for DogName or DogOwnerUserName.." />
                            <input hidden asp-for="@Model.DogFriendSearchInput" value="@Model.DogFriendSearchInput" /> 
                            </li>

                            <li>
                                <a asp-controller="DogOwner" asp-action="AddDogFriend" asp-area="" asp-route-dogId="@Model.Dog.Id" asp-route-dogFriendFirstName="DogFriendSearchInput">Add this Dog to @Model.Dog.FirstName's friendslist</a>
                            </li>
                        </div>
                    </ul>
                </div>
                <br />
            </div>

        </div><br />
    </form>

</div>

这是我当前的上下文

    public class DogFaceDbContext : IdentityDbContext<User, Role, string>
{


    public DogFaceDbContext()
    {

    }
    public virtual DbSet<Dog> Dogs { get; set; }
    public virtual DbSet<UserDog> UserDogs { get; set; }

    public virtual DbSet<DogFriend> DogFriends { get; set; }
    public virtual DbSet<Dog> DogFriendList { get; set; }

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

        builder.Entity<UserDog>().HasKey(x => new { x.DogId, x.UserId });           
        builder.Entity<DogFriend>().HasOne(x => x.Dog).WithMany(x => x.DogFriends);
        builder.Entity<Dog>().HasMany(x => x.UserDogs).WithOne(x => x.Dog);
        builder.Entity<Dog>().HasMany(x => x.DogFriends).WithOne(x => x.Dog);

        builder.Entity<User>().HasMany(x => x.UserDogs).WithOne(x => x.User);          


    }

控制器的相关部分(显然它不正确,但我想如果我有正确的 DBO,我可以自己弄清楚这部分):

    [HttpGet]
    public IActionResult AddDogFriend(int dogId)
    {

        var model = new DogViewModel();
        model.Dog = _dogFaceDbContext.Dogs.First(x => x.Id == dogId);            
        model.Dogs = _dogFaceDbContext.Dogs;
        return View(model);
    }
    [HttpPost]
    public async Task<IActionResult> AddDogFriend(int dogFriendId, string DogFriendSearchInput, AddDogFriendViewModel model)
    {
        var dogfriend = new DogFriend
        {
            DogFriendSearchInput = model.DogFriendFirstName,                
        };
        await _dogFaceDbContext.DogFriends.AddAsync(dogfriend);
        await _dogFaceDbContext.SaveChangesAsync();



        return RedirectToAction("Index", "DogOwner");
    }

非常感谢您帮助有困难的学生!

你的模型结构是错误的,如果你先写代码,那么你的数据库关系将是错误的。您的 Dog 模型中有一个循环引用:

public virtual List<Dog> DogFriendList { get; set; }

我认为如果您纠正了模型结构,您将能够更好地理解任务。你没有显示你所有的 类 所以我不确定一些虚拟的 collections 是做什么用的,但是 dog 应该看起来像这样:

      public class Dog : EntityBase<int>
      { 
        public int Id {get; set;} (PK)      
        public string FirstName { get; set; }
        public DogFertility DogFertility { get; set; }
        public DogGender DogGender { get; set; }
        public string Description { get; set; }
        public DateTime DoB { get; set; }      
        public DogBreed DogBreed { get; set; }
        public virtual List<DogFriend> DogFriends{ get; set; }
      }

现在的狗友:

      public class DogFriend : EntityBase<int>
      {
        public int Id {get; set;} (PK)
        public int DogId {get; set;} (FK)
        public string FirstName { get; set; }
        public string LastName { get; set; }
      }

狗和狗朋友之间存在 one-to-many 关系(一只狗可以有很多朋友),也可能是 many-to-many 取决于业务规则(一只狗可以有很多朋友和一条狗朋友可以成为很多狗的朋友)。

现在你的视图模型:

       public class AddDogFriendViewModel
       {
          public string DogFriendSearchInput { get; set; }
          public Dog Dog {get;set;}
       }

我暂时跳过你的 html 页面并转到控制器。你得到的将是这样的:

[HttpGet]
public IActionResult AddDogFriend(AddDogFriendViewModel model)
{

    model.Dog = new Dog();
    model.Dog = dogFaceDbContext.Dogs.Include("DogFriends").Where(d => d.FirstName == model.DogFriendSearchInput).FirstOrDefault();
    return View(model);
}

如果启用延迟加载,则不需要包含 (Dogs.Include("DogFriends"))

我的问题解决方案:

    public class Dog : EntityBase<int>
{        
    public string FirstName { get; set; }
    public DogFertility DogFertility { get; set; }
    public DogGender DogGender { get; set; }
    public string Description { get; set; }
    public DateTime DoB { get; set; }      
    public DogBreed DogBreed { get; set; }        

    public virtual List<UserDog> UserDogs { get; set; }
    public virtual List<DogFriend> DogFriends{ get; set; }       

    public Dog()
    {
        UserDogs = new List<UserDog>();
        DogFriends = new List<DogFriend>();            
    }             
}

     public class DogFriend : EntityBase<int>
{


    public int DogId { get; set; }                              //for foreign key
    [NotMapped]
    public string DogFriendSearchInput { get; set; }
    [NotMapped]
    public string DogFriendFirstName { get; set; }
    [NotMapped]
    public string DogFriendProfilePic { get; set; }
    public int DogFriendId { get; set; } 
    [NotMapped]
    public DogBreed DogBreed { get; set; }
    public Dog Dog { get; set; }

    public DogFriend()
    {

    }
}

      public class AddDogFriendViewModel
{
    public string DogFriendSearchInput { get; set; }
    public Domain.Model.Dog Dog { get; set; }

    public string DogFriendFirstName { get; set; }
    public int DogFriendId { get; set; }
    public int DogId { get; set; }
    public string ReturnUrl { get; set; }       
    public DogFriend DogFriend { get; set; }              

    public AddDogFriendViewModel()
    {

    }
}

我的 AddDogFriend 表格

    <form method="post" asp-controller="DogOwner" asp-action="AddDogFriend">
<div asp-validation-summary="ModelOnly"></div>
<div>      
    <input asp-for="DogFriendSearchInput"  placeholder="Search for DogName.." /><br />
    <span asp-validation-for="DogFriendSearchInput"></span>
</div>

<input type="hidden" asp-for="@Model.DogFriendSearchInput" value="@Model.DogFriendSearchInput" />
<input type="submit" value="Save" asp-area="" asp-route-dogId="@Model.Dog.Id" asp-route-dogFriendFirstName="DogFriendSearchInput" />   

我的背景

      public DogFaceDbContext()
    {

    }
    public virtual DbSet<Dog> Dogs { get; set; }
    public virtual DbSet<UserDog> UserDogs { get; set; }

    public virtual DbSet<DogFriend> DogFriends { get; set; }

我的 Get 和 Post 来自 Controller

    [HttpGet]
    public IActionResult AddDogFriend(int dogId)
    {

        var model = new DogViewModel();
        model.Dog = _dogFaceDbContext.Dogs.First(x => x.Id == dogId);


        model.Dogs = _dogFaceDbContext.Dogs;
        return View(model);
    }
    [HttpPost]
    public async Task<IActionResult> AddDogFriend(int dogId, string DogFriendSearchInput, AddDogFriendViewModel model)
    {
        var dog = _dogFaceDbContext.Dogs.First(x => x.Id == dogId);
        var dogFriendToAdd  = _dogFaceDbContext.Dogs.First(x => x.FirstName == DogFriendSearchInput);

        dog.DogFriends.Add(new DogFriend { DogId = dog.Id, DogFriendId = dogFriendToAdd.Id });

        await _dogFaceDbContext.SaveChangesAsync();
        return RedirectToAction("Index", "DogOwner");
    }

如有其他问题,请随时提问!