簡體   English   中英

如何在服務層中使用 AsNoTracking

[英]How to use AsNoTracking in a service layer

當我不打算寫任何東西時,我通常使用 AsNoTracking。 我應該如何在 dbContext 隱藏在它后面的服務層中處理這個問題? (我將 EF 核心視為存儲庫,因為它是存儲庫)

public class SomeService
{
    //...

    public SomeEntity GetById(int id)
    {
        return _dbContext.Find(id);
    }

    public SomeEntity GetReadonlyById(int id)
    {
        return _dbContext.SomeEntitities.AsNoTracking().SingleOrDefault(e => e.Id == id);
    }

    public SomeEntity Update(SomeEntity someEntity)
    {
        _dbContext.Update(someEntity);
        _dbContext.SaveChanges();
    }
}

public class SomeController
{
    private readonly SomeService _someService;

    //....

    [HttpGet("{id}")]
    public IActionResult Get(int id)
    {
        var someEntity = _someService.GetReadonlyById(id);
        if (someEntity == null)
        {
            return NotFound();
        }
        return someEntity;
    }

    [HttpPut("{id}")]
    public IActionResult Modify(int id, SomeEntity modified)
    {
        var someEntity = _someService.GetById(id);
        if (someEntity == null)
        {
            return NotFound();
        }
        someEntity.Someproperty = modified.Someproperty;
        _someService.Update(someEntity);
        return Ok(someEntity);
    }
}

有沒有更好的方法來做到這一點?

我還可以如下定義我的服務:

public class SomeService
{
    //...

    public SomeEntity GetById(int id)
    {
        return _dbContext.AsNoTracking.SingleOrDefault(e => e.Id == id);
    }

    public SomeEntity Update(int id, SomeEntity someEntity)
    {
        var entity = _dbContext.SomeEntities.Find(id);
        if (entity == null)
        {
            return null;
        }
        entity.Someproperty = someEntity.Someproperty;
        _dbContext.Update(entity);
        _dbContext.SaveChanges();
        return entity;
    }
}

public class SomeController
{
    private readonly SomeService _someService;

    //....

    [HttpGet("{id}")]
    public IActionResult Get(int id)
    {
        var someEntity = _someService.GetById(id);
        if (someEntity == null)
        {
            return NotFound();
        }
        return someEntity;
    }

    [HttpPut("{id}")]
    public IActionResult Modify(int id, SomeEntity modified)
    {
        var someEntity = _someService.Update(id, modified);
        if (someEntity == null)
        {
            return NotFound();
        }
        return Ok(someEntity);
    }
}

更好的方法是什么?

基本上,這是更常見的問題。

經常出現優化的讀取方式不方便更新場景,方便的讀取方式更新場景對只讀場景有不必要的開銷。 我在這里看到 3 個選項:

  1. 忽略所有性能問題,只使用第一種方法中的通用GetById進行讀取和更新。 顯然,它適用於簡單的應用,可能不適用於高負載的應用。
  2. 使用CQRS 這意味着您將擁有完全獨立的數據 model 用於讀取和更新。 由於讀取通常不需要復雜的域邏輯,它允許您使用任何優化,如AsNoTracking方法,甚至在存儲庫中使用普通的sql 它適用於復雜的應用程序並且需要更多的代碼。
  3. 嘗試根據您的特定需求在這兩個選項之間找到一些折衷方案。

如評論中所述,您的SomeService看起來像存儲庫。 理想情況下,域服務應該只包含業務邏輯,而不應該將其與AsNoTracking等基礎設施功能混合。 而存儲庫可以並且應該包含基礎設施功能,如AsNoTrackingInclude等。

當結果用於只讀方案時,沒有跟蹤查詢是有用的。 它們執行速度更快,因為無需設置更改跟蹤信息。

您可以將單個查詢交換為不跟蹤:

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .AsNoTracking()
        .ToList();
}

您還可以在上下文實例級別更改默認跟蹤行為:

using (var context = new BloggingContext())
{
    context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

    var blogs = context.Blogs.ToList();
}

理想情況下,您應該在存儲庫級別管理基礎設施。

這是我的解決方案。 有用。

所有服務的基礎 CLASS

public class ServicesBase
            {
                protected AppDbContext dbcontext { get; }
      
                public ServicesBase(AppDbContext dbcontext)
                {
                    this.dbcontext = dbcontext;      
                }
        
                public void AsNoTracking()
                {
                    dbcontext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
                }
        
                public void SaveChanges()
                {
                    dbcontext.SaveChanges();
                }
        
            }

在 CONTROLLER 中使用

_masterService.AsNoTracking();
var master = _masterService.GetById(1);
master.WagePerSquareMeter = 21;
_masterService.SaveChanges(); 

//or dbcontext.SaveChanges(), both of them will ot affect the database.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM