创建/删除/更新方法应该有自己的保存方法吗?实体框架

本文关键字:方法 保存 实体 框架 自己的 更新 删除 新方法 创建 | 更新日期: 2023-09-27 18:34:44

我读到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 次调用 db,如果一个失败,它们都会回滚(您当然可以提出这些是分开的论点,如果可以插入城市,那么为什么不这样做(

我看到的一个问题是,如果其他人从控制器调用 CreateCity,因为我可以直接将城市插入我的数据库中,那么控制器将需要执行context.SaveChanges()这将是不好的,或者我必须有一个名为 CreateAndSaveCity((;

创建/删除/更新方法应该有自己的保存方法吗?实体框架

我不建议调用保存更改,而不是共享代码(即只调用一次FindVenue()(。

为了解决其他想要拯救城市的方法的问题,这里有几个想法......

选项 1:创建一个创建城市的重载方法(如您所建议的,类似于 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 以设置外键(,则没有理由进行数据库往返。

SaveChangesCreateCity() 括起来,用TransactionScope包裹起来。

public void FindVenue()
{
   using (var trans = new TransactionScope()) {
       CreateCity();
       // some code to add your venue...
       // ...
       context.SaveChanges();
       trans.Commit();
   }
}