【问题标题】:Entity Framework with Repository Pattern, inserting data to tables with many-to-many relationship具有存储库模式的实体框架,将数据插入到具有多对多关系的表中
【发布时间】:2018-03-05 20:02:58
【问题描述】:

我正在尝试使用 BLL、DAL 和 UI 构建三层架构。我正在做一个小型公寓管理系统项目(其中包括关于住校学生、他们的房间和他们住的房间的公寓的信息)。由于我是初学者,因此我需要解决一些技术问题。我正在使用具有存储库模式的实体框架。我的项目基于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>();
        });
    }
}

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

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 接口。我已经创建了我的存储库和基础架构:

基础设施(文件夹)

  • IApartmentRepository.cs
  • IRepository.cs
  • IRoomRepository.cs
  • IStudentRepository.cs
  • IUserRepository.cs

存储库(文件夹)

  • ApartmentRepository.cs
  • RoomRepository.cs
  • StudentRepository.cs
  • UserRepository.cs

添加新房间时,管理员必须说明该房间属于哪个公寓。 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);
        }
    }

房间视图模型

 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; }
}

用户界面

Room Add UI

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

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

编辑 1:我使用的是数据库优先方法。

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

【问题讨论】:

    标签: asp.net-mvc entity-framework repository-pattern data-access-layer business-logic-layer


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      [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);
          }
      }
      

      【讨论】:

        【解决方案3】:

        我已经设法找到了解决方案。首先,我在 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

        这个类已经从我的数据库中生成了。

        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

        我已经创建了这个类。

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

        房间控制器

        我稍微改变了RoomController的内部。我创建了一个 _entities 对象,以便能够将数据插入到 ApartmentRoom 表中。

        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 表中添加了一个新房间后,我调用了最后插入的房间的 Id 值来对ApartmentRoom 表进行新的插入。

        结果

        公寓房桌

        房间桌

        【讨论】:

        • 我假设 roomViewModel 中的 ID 在插入控制器时为零。也许您也可以尝试Room.ApartmentRoom.ApartmentID = roomViewModel.ApartmentNameID; Room.ApartmentRoom.RoomID = roomViewModel.RoomID;之类的方法,我知道此时 RoomID 仍然为零,但是当您添加两个实体然后保存它们时,数据库会为您创建 id 并自动分配正确的值。如果你尝试,让我知道会发生什么。我很感兴趣。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-30
        • 1970-01-01
        • 2013-07-20
        • 1970-01-01
        • 1970-01-01
        • 2011-11-02
        • 1970-01-01
        相关资源
        最近更新 更多