我读到EF本身就是一个工作单元和存储库,所以我真的不想创建一个存储库层和另一个UoW,除非真的有必要。
但是我对此感到疑惑。我有城市服务和场地服务。我有一个FindVenue方法
public void FindVenue()
{
// find venue in db
// If not in db - find from 3rd party api
// If from 3rd party api check if city exits in db
// If city does not exist create a city record in db
// If venue does not exist create a new venue record in db
context.SaveChanges();
}
现在我想知道CreateCity方法应该有context.SaveChanges();
还是应该将它添加到DbSet中,然后当在FindVenue中创建新的场地时,它可以插入两个记录。
这种方式只有1次调用数据库,如果一次失败,它们都会被回滚(你当然可以认为这些是分开的,如果城市可以插入那么为什么不这样做)
我看到的一个问题是,如果有其他人从控制器调用CreateCity,因为我可以直接将City插入我的数据库,那么控制器需要执行context.SaveChanges()
会很糟糕,或者我必须有一个名为CreateAndSaveCity();
答案 0 :(得分:0)
我建议您不要仅仅为了共享代码而调用保存更改(即只为FindVenue()
调用一次)。
要解决其他想要保存城市的方法的问题,这里有几点想法......
选项1:创建一个create city的重载方法(就像你建议的那样,类似CreateAndSaveCity
),可以调用第一个方法CreateCity
(不保存更改) )然后保存更改
public void FindVenue()
{
// find venue in db
// If not in db - find from 3rd party api
// If from 3rd party api check if city exits in db
// If city does not exist...
CreateCity(context);
// If venue does not exist create a new venue record in db
context.SaveChanges();
}
public void CreateCity(YourContext context)
{
// Create city, don't save changes
}
public void CreateAndSaveCity(YourContext context)
{
CreateCity();
context.SaveChanges();
}
在这种情况下,如果您想从其他地方的控制器创建城市,可以拨打CreateAndSaveCity(context)
选项2:让CreateCity
方法采用可选的布尔参数来指示是否应保存更改。根据最常见的用例,您可以将可选参数的默认值设置为true或false,如果要确保始终明确指定,则使其成为必需参数。
public void FindVenue()
{
// find venue in db
// If not in db - find from 3rd party api
// If from 3rd party api check if city exits in db
// If city does not exist...
CreateCity(context);
// If venue does not exist create a new venue record in db
context.SaveChanges();
}
public void CreateCity(YourContext context, bool saveChanges = false)
{
// Create city
if (saveChanges) {
context.SaveChanges();
}
}
在这种情况下,如果您想从其他地方的控制器创建城市,可以拨打CreateCity(context, true)
就个人而言,我更喜欢选项2,但这主要是语义问题。
另外,关于你的评论:
你当然可以说这些是分开的,如果是的话 城市可以插入然后为什么不这样做
这取决于业务逻辑的需求。但即使在这种情况下,您仍然可以在检查是否应创建场地之后保存更改(并在需要时创建)。如果您实际上需要要单独保存城市(例如,为了在插入后获取其ID以设置外键),则没有理由使数据库往返。
答案 1 :(得分:0)
SaveChanges
中的CreateCity()
并将其换成TransactionScope
。
public void FindVenue()
{
using (var trans = new TransactionScope()) {
CreateCity();
// some code to add your venue...
// ...
context.SaveChanges();
trans.Commit();
}
}