Entity Framework 使用存储库模式,向具有多对多关系的表插入数据

Entity Framework with Repository Pattern, inserting data to tables with many-to-many relationship

我正在尝试使用 BLL、DAL 和 UI 构建一个三层架构。我正在从事一个小型公寓管理系统项目(其中包括有关住宿学生、他们的房间和他们所住房间的公寓的信息)。由于我是初学者,我有一些技术问题需要解决。我正在使用 Entity Framework 和存储库模式。我的项目基于 MVVM 方法,我正在使用 Automapper.

Automapper 代码

public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Room, RoomViewModel>().ReverseMap();
        CreateMap<Apartment, ApartmentViewModel>().ReverseMap();
    }
}

public class AutoMapperConfig
{
    public static void Configure()
    {
        Mapper.Initialize(x =>
        {
            x.AddProfile<AutoMapperProfile>();
        });
    }
}

我正在尝试向我的数据库中添加一个新房间。我的房间和公寓 table 之间存在多对多关系,我的数据库如下所示:

My Database's screen shot

我的 IRepository 界面如下所示:

public interface IRepository<T> where T : class
{
    IEnumerable<T> GetAll();
    T GetById(int id);
    T Get(Expression<Func<T, bool>> expression);
    IQueryable<T> GetMany(Expression<Func<T, bool>> expression);
    bool Insert(T obj);
    bool Update(T obj);
    bool Delete(int id);
    int Count();
    void Save();
}

我有 RoomRepository 和 ApartmentRepository,它们都实现了 IRepository 接口。我已经创建了我的存储库和基础设施:

基础架构(文件夹)

存储库(文件夹)

添加新房间时,管理员必须说明该房间属于哪个公寓。 RoomController 中的 Add 方法如下:

[HttpPost]
    public JsonResult Add(RoomViewModel roomModel)
    {
        try
        {
            //var apartViewModel = new ApartmentRoomViewModel();
            //apartViewModel.ApartmentID = roomModel.ApartmentNameId;
            var room = AutoMapper.Mapper.Map<Room>(roomModel);
            var status = _roomRepository.Insert(room);
            _roomRepository.Save();
            //apartViewModel.RoomID = room.Id;

            return Json(new { status, message = "Ekleme işlemi başarılı." }, JsonRequestBehavior.AllowGet);
        }
        catch (Exception)
        {
            return Json(new { status = false, message = "Hata! Ekleme işlemi gerçekleştirilemedi." }, JsonRequestBehavior.AllowGet);
        }
    }

RoomViewModel

 public class RoomViewModel
{

    public int Id { get; set; }

    public int DoorNumber { get; set; }

    public int FloorNumber { get; set; }

    public int Capacity { get; set; }

    public int Fullness { get; set; }

    public string ApartmentName { get; set; }

    public int ApartmentNameId { get; set; }
}

UI

Room Add UI

我的问题是,当我想在房间添加页面中插入从用户那里获取的数据时,我可以将为房间收集的信息添加到房间 table 但我还想添加该房间的公寓信息(即该公寓的 ApartmentID)和同一个房间的 RoomID 到数据库中的 ApartmentRoom table,到目前为止我无法做到这一点。如果到目前为止我没有错,那我该怎么办?

  1. 我是否应该创建另一个存储库,如实现 IRepository 接口的 ApartmentRoomRepository,并在 RoomController 的 Add 方法中调用 ApartmentRoomRepository 的插入方法? (据我所知,这种方法似乎不太正确,但我不确定。)
  2. 我应该创建 ApartmentRoomViewModel 而不是第一个选项吗?在这种情况下,如何将带有房间 RoomID 的房间的 ApartmentID 插入到 ApartmentRoom table?

编辑 1:我正在使用数据库优先方法。

编辑 2:我找到了解决方案并在下面作为答案分享。

我从未使用过自动映射器功能,并且有单独的 modelviewmodel 对象,但在这种情况下我会创建一个新的 ApartmentRoom 对象以及新的Room 对象,将它们都保存到数据库中。创建的 ApartmentRoom 模型是存储链接信息的地方。 EF对于多对多关系不是很明显

如果你确定你处理域 类 并且流利 API 我也认为你玩的不是 EF 核心。您可以从 ApartmentRepository 获取 Apartment 然后将其添加到房间 apartments 并将其添加到数据库。

[HttpPost]
public JsonResult Add(RoomViewModel roomModel)
{
    try
    {
        //var apartViewModel = new ApartmentRoomViewModel();
        //apartViewModel.ApartmentID = roomModel.ApartmentNameId;
        var room = AutoMapper.Mapper.Map<Room>(roomModel);
        var apart= apartmentRepository.GetById(roomModel.ApartmentNameId);
        room.Apartments.Add(apart);
        var status = _roomRepository.Insert(room);
        _roomRepository.Save();
        //apartViewModel.RoomID = room.Id;

        return Json(new { status, message = "Ekleme işlemi başarılı." }, JsonRequestBehavior.AllowGet);
    }
    catch (Exception)
    {
        return Json(new { status = false, message = "Hata! Ekleme işlemi gerçekleştirilemedi." }, JsonRequestBehavior.AllowGet);
    }
}

我已经设法找到解决方案。首先,我在 AutoMapperProfile.cs 文件中添加了一行。

AutoMapperProfile.cs

 public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Room, RoomViewModel>().ReverseMap();
        CreateMap<Apartment, ApartmentViewModel>().ReverseMap();

        // Added this new line
        CreateMap<ApartmentRoom, ApartmentRoomViewModel>().ReverseMap();
    }
}

public class AutoMapperConfig
{
    public static void Configure()
    {
        Mapper.Initialize(x =>
        {
            x.AddProfile<AutoMapperProfile>();
        });
    }
}

ApartmentRoom.cs

这个 class 已经从我的数据库生成。

public partial class ApartmentRoom
{
    public int Id { get; set; }
    public int ApartmentID { get; set; }
    public int RoomID { get; set; }

    public virtual Apartment Apartment { get; set; }
    public virtual Room Room { get; set; }
}

ApartmentRoomViewModel.cs

我创建了这个 class。

public class ApartmentRoomViewModel
{
    public int ApartmentID { get; set; }
    public int RoomID { get; set; }
}

房间控制器

我对 RoomController 的内部做了一点改动。我创建了一个 _entities 对象,以便能够将数据插入 ApartmentRoom table.

public class RoomController : Controller
{
    ApartmentManSysEntities _entities = new ApartmentManSysEntities();
    private readonly IRoomRepository _roomRepository;
    private readonly IApartmentRepository _apartmentRepository;
    public RoomController(IRoomRepository roomRepository, IApartmentRepository apartmentRepository)
    {
        _roomRepository = roomRepository;
        _apartmentRepository = apartmentRepository;
    }

    [HttpPost]
    public JsonResult Add(RoomViewModel roomViewModel)
    {
        try
        {
            var room = AutoMapper.Mapper.Map<Room>(roomViewModel);
            if (_roomRepository.Insert(room))
            {
                _roomRepository.Save();
                var apartRoomViewModel = new ApartmentRoomViewModel
                {
                    ApartmentID = roomViewModel.ApartmentNameID,
                    RoomID = room.Id
                };
                var apartRoom = AutoMapper.Mapper.Map<ApartmentRoom>(apartRoomViewModel);
                _entities.ApartmentRoom.Add(apartRoom);
                _entities.SaveChanges();
            }
            else
            {
                return Json(new { status = false, message = "Hata! Ekleme işlemi gerçekleştirilemedi." }, JsonRequestBehavior.AllowGet);
            }
            return Json(new { status = true, message = "Ekleme işlemi başarılı." }, JsonRequestBehavior.AllowGet);
        }
        catch
        {
            return Json(new { status = false, message = "Hata! Ekleme işlemi gerçekleştirilemedi." }, JsonRequestBehavior.AllowGet);
        }
    }

}

我在Room table中添加了一个新房间后,我调用了最后插入的房间的Id值来对ApartmentRoom table进行了新的插入。

结果

公寓房间table

房间table