具有存储库模式的实体框架,将数据插入到具有多对多关系的表中
Posted
技术标签:
【中文标题】具有存储库模式的实体框架,将数据插入到具有多对多关系的表中【英文标题】: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 表,到目前为止我还不能这样做。如果到目前为止我没有错,那我该怎么办?
-
我是否应该创建另一个存储库,例如实现IRepository接口的ApartmentRoomRepository,并在RoomController内部的Add方法中调用ApartmentRoomRepository的insert方法? (据我了解,这种方法似乎不太正确,但我不确定。)
我应该创建 ApartmentRoomViewModel,而不是第一个选项?在这种情况下,如何将房间的 ApartmentID 与房间的 RoomID 插入到 ApartmentRoom 表中?
编辑 1:我使用的是数据库优先方法。
编辑 2:我找到了解决方案并在下面分享为答案。
【问题讨论】:
【参考方案1】:我从未使用过自动映射器功能,并且有单独的 model
和 viewmodel
对象,但在这种情况下,我将创建一个新的 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 并自动分配正确的值。如果你尝试,让我知道会发生什么。我很感兴趣。以上是关于具有存储库模式的实体框架,将数据插入到具有多对多关系的表中的主要内容,如果未能解决你的问题,请参考以下文章