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 接口。我已经创建了我的存储库和基础设施:
基础架构(文件夹)
- 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);
}
}
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,到目前为止我无法做到这一点。如果到目前为止我没有错,那我该怎么办?
- 我是否应该创建另一个存储库,如实现 IRepository 接口的 ApartmentRoomRepository,并在 RoomController 的 Add 方法中调用 ApartmentRoomRepository 的插入方法? (据我所知,这种方法似乎不太正确,但我不确定。)
- 我应该创建 ApartmentRoomViewModel 而不是第一个选项吗?在这种情况下,如何将带有房间 RoomID 的房间的 ApartmentID 插入到 ApartmentRoom table?
编辑 1:我正在使用数据库优先方法。
编辑 2:我找到了解决方案并在下面作为答案分享。
我从未使用过自动映射器功能,并且有单独的 model
和 viewmodel
对象,但在这种情况下我会创建一个新的 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
我正在尝试使用 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 接口。我已经创建了我的存储库和基础设施:
基础架构(文件夹)
- 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);
}
}
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,到目前为止我无法做到这一点。如果到目前为止我没有错,那我该怎么办?
- 我是否应该创建另一个存储库,如实现 IRepository 接口的 ApartmentRoomRepository,并在 RoomController 的 Add 方法中调用 ApartmentRoomRepository 的插入方法? (据我所知,这种方法似乎不太正确,但我不确定。)
- 我应该创建 ApartmentRoomViewModel 而不是第一个选项吗?在这种情况下,如何将带有房间 RoomID 的房间的 ApartmentID 插入到 ApartmentRoom table?
编辑 1:我正在使用数据库优先方法。
编辑 2:我找到了解决方案并在下面作为答案分享。
我从未使用过自动映射器功能,并且有单独的 model
和 viewmodel
对象,但在这种情况下我会创建一个新的 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