locked
Does AsNoTracking have any risks? RRS feed

  • Question

  • User283528319 posted

    hi all,

    Does AsNoTracking have any risk?

    Like one client insert a record and get a indetiy like (101) and other also get the same and 2. one updates the first record instead of his?

    Saturday, October 19, 2019 3:54 PM

Answers

  • User765422875 posted

    <g class="gr_ gr_5 gr-alert gr_gramm gr_inline_cards gr_run_anim Punctuation only-ins replaceWithoutSep" id="5" data-gr-id="5">Generally</g> you do not want to use AsNoTracking() unless you are retrieving data that will not be changed. If you use it and the entity instances are modified, changes will not be detected by the change tracker, and SaveChanges() will not persist those changes to the database.

    If you want to use AsNoTracking() but update an entity, you have to <g class="gr_ gr_68 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del" id="68" data-gr-id="68">Attach</g> it to the context.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, October 22, 2019 3:59 PM

All replies

  • User1120430333 posted

    fatihbarut

    hi all,

    Does AsNoTracking have any risk?

    Like one client insert a record and get a indetiy like (101) and other also get the same and 2. one updates the first record instead of his?

    AsNoTracking  has nothing to do with concurrency that you are talking about. AsNoTracking  has to do with the state of the entity and is basically about is  the entity dirt, a change occurred, and ready to be saved. Basically,  AsNoTracking  is worthless in a Web solution concerning EF, becuase Web solutions are stateless., and I never bother with it or enable it.

    https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.entityframeworkqueryableextensions.asnotracking?view=efcore-3.0

    https://www.entityframeworktutorial.net/EntityFramework5/handle-concurrency-in-entity-framework.aspx

    Sunday, October 20, 2019 10:32 AM
  • User283528319 posted

    fatihbarut

    hi all,

    Does AsNoTracking have any risk?

    Like one client insert a record and get a indetiy like (101) and other also get the same and 2. one updates the first record instead of his?

    AsNoTracking  has nothing to do with concurrency that you are talking about. AsNoTracking  has to do with the state of the entity and is basically about is  the entity dirt, a change occurred, and ready to be saved. Basically,  AsNoTracking  is worthless in a Web solution concerning EF, becuase Web solutions are stateless., and I never bother with it or enable it.

    https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.entityframeworkqueryableextensions.asnotracking?view=efcore-3.0

    https://www.entityframeworktutorial.net/EntityFramework5/handle-concurrency-in-entity-framework.aspx

    could you clarify please, asnotracking means nothing in .net core 3.0 projects?

    Sunday, October 20, 2019 10:48 AM
  • User1120430333 posted

    fatihbarut

    DA924

    fatihbarut

    hi all,

    Does AsNoTracking have any risk?

    Like one client insert a record and get a indetiy like (101) and other also get the same and 2. one updates the first record instead of his?

    AsNoTracking  has nothing to do with concurrency that you are talking about. AsNoTracking  has to do with the state of the entity and is basically about is  the entity dirt, a change occurred, and ready to be saved. Basically,  AsNoTracking  is worthless in a Web solution concerning EF, becuase Web solutions are stateless., and I never bother with it or enable it.

    https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.entityframeworkqueryableextensions.asnotracking?view=efcore-3.0

    https://www.entityframeworktutorial.net/EntityFramework5/handle-concurrency-in-entity-framework.aspx

    could you clarify please, asnotracking means nothing in .net core 3.0 projects?

    A Web server gets a request, processes a request, and returns a response in a completely stateless manner. Every request, even from the same client a moment later, looks brand new to the server.

    AsNoTracking if enabled is lost the moment a response  is sent back, and the  Web server returns control to the clinet. The only way AsNoTracking would work is if a change to an entity is done and the SaveChanges() was done in the same context scope, like you get the entity for update in a context scope, you change the entity within the context scope and you save the entity within the context scope. If there is some kind of validation error returning control back to the client as an example,  then  AsNoTracking state, what it knew about for an entity that had changed and is dirty,  is lost, becuase the Web server is stateless. 

    Also if the EF is sitting behind a Web service,  AsNoTracking is not traveling between the client and the service. If one is using n-tier or layered architecture using a layer such as a data access layer or repository layer, a classlib project, then  AsNoTracking is not traveling between the layers and is not functional. 

    ----------------------------------------------------------------------------------------

    correction

    If change tracking is enabled, it will be lost becuase of the stateless behavior of a Web server and also based on the other situations I have explained. 

    Sunday, October 20, 2019 11:23 AM
  • User475983607 posted

    fatihbarut

    could you clarify please, asnotracking means nothing in .net core 3.0 projects?

    In a typical web application the DbContext is created at the beginning of the request and torn down at the end.   There is no need to enable the change tracker unless you're changing data and invoking SaveChanges() during a request.  An HTTP GET request is a common scenario where change tracking is disabled because the data is used for presentation.   An HTTP POST request is typically where you'll see change tracking because the user is requesting a save. 

    Concurrency is a design consideration in every data driven application regardless of change tracking.  The Entity Framework documentation covers common programming patterns for dealing with concurrency.  I recommend starting with the docs.

    https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/concurrency?view=aspnetcore-3.0

    https://docs.microsoft.com/en-us/ef/core/saving/concurrency

    Sunday, October 20, 2019 11:54 AM
  • User765422875 posted

    <g class="gr_ gr_5 gr-alert gr_gramm gr_inline_cards gr_run_anim Punctuation only-ins replaceWithoutSep" id="5" data-gr-id="5">Generally</g> you do not want to use AsNoTracking() unless you are retrieving data that will not be changed. If you use it and the entity instances are modified, changes will not be detected by the change tracker, and SaveChanges() will not persist those changes to the database.

    If you want to use AsNoTracking() but update an entity, you have to <g class="gr_ gr_68 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del" id="68" data-gr-id="68">Attach</g> it to the context.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, October 22, 2019 3:59 PM
  • User1120430333 posted

    Generally you do not want to use AsNoTracking() unless you are retrieving data that will not be changed. If you use it and the entity instances are modified, changes will not be detected by the change tracker, and SaveChanges() will not persist those changes to the database.

    If you want to use AsNoTracking() but update an entity, you have to Attach it to the context.

    However, if one is using SoC with a layer such as a data access layer is being used and the EF entity is left at the DAL and not sent, one doesn't  Attach you don't need it. How is change tracking or no change  tracking is of any consequence or even doing an Attach is of any use in such a scenario?

    https://en.wikipedia.org/wiki/Separation_of_concerns

    using System;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using DAL.Models;
    using Entities;
    using Microsoft.EntityFrameworkCore;
    
    namespace DAL
    {
        public class DaoArticle :IDaoArticle
        {
            private PublishingCompanyContext pc;
            private IDaoAuthor _daoAuthor;
    
            public DaoArticle(PublishingCompanyContext dbcontext, IDaoAuthor daoAuthor)
            { 
                pc = dbcontext;
                _daoAuthor = daoAuthor;
            }
            public async Task<List<DtoArticle>> GetAll()
            {
                var dtos = new List<DtoArticle>();
    
                var articles = await pc.Article.ToListAsync();
    
                dtos.AddRange(articles.Select(article => new DtoArticle()
                {
                    ArticleId = article.ArticleId,
                    AuthorId = article.AuthorId,
                    Title = article.Title,
                    Body = article.Body
                }).ToList());
    
                return dtos;
            }
    
            public async Task<List<DtoArticle>> GetArticlesByAuthorId(int id)
            {
                var dtos = new List<DtoArticle>();
    
                var articles = await pc.Article.Where(a => a.AuthorId.ToString().Contains(id.ToString())).ToListAsync();
               
                foreach (var article in articles)
                {
                    var intid = (int)article.AuthorId;
    
                    var dtoauthor = await _daoAuthor.Find(intid);
    
                    var dto = new DtoArticle
                    {
                        ArticleId = article.ArticleId,
                        AuthorId = article.AuthorId,
                        AuthorName = dtoauthor.LastName +", " + dtoauthor.FirstName,
                        Title = article.Title,
                        Body = article.Body
                    };
    
                    dtos.Add(dto);
                }
                 
                return dtos;
            }
    public async Task<DtoArticle> Find(int id) { var dto = new DtoArticle(); var article = await pc.Article.FindAsync(id); if (article != null) { dto.ArticleId = article.ArticleId; dto.AuthorId = article.AuthorId; dto.Title = article.Title; dto.Body = article.Body; } else { throw new Exception($"Article with ID = {id} was not found."); } return dto; } public async Task Add(DtoArticle dto) { var article = new Article { AuthorId = dto.AuthorId, Title = dto.Title, Body = dto.Body }; pc.Article.Add(article); await pc.SaveChangesAsync(); } public async Task Update(DtoArticle dto) { var article = new Article { ArticleId = dto.ArticleId, AuthorId = dto.AuthorId, Title = dto.Title, Body = dto.Body }; pc.Entry(article).State = EntityState.Modified; await pc.SaveChangesAsync(); } public async Task Delete(int id) { var article = pc.Article.Find(id); if (article != null) { pc.Article.Remove(article); await pc.SaveChangesAsync(); } } } }

    Tuesday, October 22, 2019 7:32 PM
  • User283528319 posted

    deepalgorithm

    Generally you do not want to use AsNoTracking() unless you are retrieving data that will not be changed. If you use it and the entity instances are modified, changes will not be detected by the change tracker, and SaveChanges() will not persist those changes to the database.

    If you want to use AsNoTracking() but update an entity, you have to Attach it to the context.

    However, if one is using SoC with a layer such as a data access layer is being used and the EF entity is left at the DAL and not sent, one doesn't  Attach you don't need it. How is change tracking or no change  tracking is of any consequence or even doing an Attach is of any use in such a scenario?

    https://en.wikipedia.org/wiki/Separation_of_concerns

    using System;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using DAL.Models;
    using Entities;
    using Microsoft.EntityFrameworkCore;
    
    namespace DAL
    {
        public class DaoArticle :IDaoArticle
        {
            private PublishingCompanyContext pc;
            private IDaoAuthor _daoAuthor;
    
            public DaoArticle(PublishingCompanyContext dbcontext, IDaoAuthor daoAuthor)
            { 
                pc = dbcontext;
                _daoAuthor = daoAuthor;
            }
            public async Task<List<DtoArticle>> GetAll()
            {
                var dtos = new List<DtoArticle>();
    
                var articles = await pc.Article.ToListAsync();
    
                dtos.AddRange(articles.Select(article => new DtoArticle()
                {
                    ArticleId = article.ArticleId,
                    AuthorId = article.AuthorId,
                    Title = article.Title,
                    Body = article.Body
                }).ToList());
    
                return dtos;
            }
    
            public async Task<List<DtoArticle>> GetArticlesByAuthorId(int id)
            {
                var dtos = new List<DtoArticle>();
    
                var articles = await pc.Article.Where(a => a.AuthorId.ToString().Contains(id.ToString())).ToListAsync();
               
                foreach (var article in articles)
                {
                    var intid = (int)article.AuthorId;
    
                    var dtoauthor = await _daoAuthor.Find(intid);
    
                    var dto = new DtoArticle
                    {
                        ArticleId = article.ArticleId,
                        AuthorId = article.AuthorId,
                        AuthorName = dtoauthor.LastName +", " + dtoauthor.FirstName,
                        Title = article.Title,
                        Body = article.Body
                    };
    
                    dtos.Add(dto);
                }
                 
                return dtos;
            }
    
            public async Task<DtoArticle> Find(int id)
            {
                var dto = new DtoArticle();
    
                var article = await pc.Article.FindAsync(id);
                
                if (article != null)
                {
                    dto.ArticleId = article.ArticleId;
                    dto.AuthorId = article.AuthorId;
                    dto.Title = article.Title;
                    dto.Body = article.Body;
                }
                else
                {
                    throw new Exception($"Article with ID = {id} was not found.");
                }
    
                return dto;
    
            }
    
            public async Task Add(DtoArticle dto)
            {
                var article = new Article
                {
                    AuthorId = dto.AuthorId,
                    Title = dto.Title,
                    Body = dto.Body
                };
    
                pc.Article.Add(article);
                await pc.SaveChangesAsync();
    
            }
    
            public async Task Update(DtoArticle dto)
            {
                var article = new Article
                {
                    ArticleId = dto.ArticleId,
                    AuthorId = dto.AuthorId,
                    Title = dto.Title,
                    Body = dto.Body
                };
    
                pc.Entry(article).State = EntityState.Modified;
                await pc.SaveChangesAsync();
    
            }
    
            public async Task Delete(int id)
            {
                var article = pc.Article.Find(id);
    
                if (article != null)
                {
                    pc.Article.Remove(article);
                    await pc.SaveChangesAsync();
                }
            }
    
        }
    }
    

    Could you explain it to me, while EF creates a perfect DAL why anyone needs another DAL built manually beside EF?

    Tuesday, October 22, 2019 8:18 PM
  • User1120430333 posted

    Could you explain it to me, while EF creates a perfect DAL why anyone needs another DAL built manually beside EF?

    It doesn't matter if an ORM like EF is being used in the DAL, It doesn't matter if  database command objects are being used using inline dynamic T-SQL or stored procedure using datasets and datatables or a collection of custom object such as a DTO are being used in the DAL. It's about seperation of concerns aka SoC.

    https://en.wikipedia.org/wiki/Separation_of_concerns

    It's about layered, n-tier or a combination of styles the main ones  that implement SoC.

    https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee658117(v=pandp.10)

    Tuesday, October 22, 2019 11:16 PM
  • User283528319 posted

    Could you explain it to me, while EF creates a perfect DAL why anyone needs another DAL built manually beside EF?

    It doesn't matter if an ORM like EF is being used in the DAL, It doesn't matter if  database command objects are being used using inline dynamic T-SQL or stored procedure using datasets and datatables or a collection of custom object such as a DTO are being used in the DAL. It's about seperation of concerns aka SoC.

    https://en.wikipedia.org/wiki/Separation_of_concerns

    It's about layered, n-tier or a combination of styles the main ones  that implement SoC.

    https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee658117(v=pandp.10)

    In MVC structure, You do all your db requests in the Controller and it solves all concerns* :) that is what I know. *Doesn't it?

    Wednesday, October 23, 2019 6:16 AM
  • User1120430333 posted

    In MVC structure, You do all your db requests in the Controller and it solves all concerns* :) that is what I know. *Doesn't it?

    ASP.NET MVC, MS's version of MVC,  is just a UI design pattern that implements seperation of duty aka SoD.  MVC has been used for decades starting out on the desktop.

    https://en.wikipedia.org/wiki/Model–view–controller

    <copied>
    Traditionally used for desktop graphical user interfaces (GUIs), this pattern has become popular for designing web applications.[4] Popular programming languages like JavaScript, Python, Ruby, PHP, Java, and C# have MVC frameworks that are used in web application development straight out of the box.
    <end>

    https://www.codeproject.com/Articles/383153/The-Model-View-Controller-MVC-Pattern-with-Csharp

    Most developers such as yourself don't know how to arcutect a MVC solution, and you  can and do  easily and continuously violate the principles of using the MVC UI design pattern in using ASP.NET MVC. The vast majority of developers use the simplistic teachings one has been taught from books and tutorials about ASP.NET MVC,  and they can take it no further beyond what they have been taught in effectively developing and architecting solutions. 

    Instead of loosely developing a solution,  you are creating a tightly coupled solution with everything sitting in the UI project, which is typical for a ASP.NET MVC developer that doesn't know any better and doesn't know how to arcutect.  

    https://www.codeproject.com/Articles/228214/Understanding-Basics-of-UI-Design-Pattern-MVC-MVP

    I used MVP and MVVM well before I got to MVC in developing enterprise level solutions using layered or n-tier achtecture. . So I knew better than what the basics that were being taught in books and tutorials about ASP.NET MVC, and I sought out material about what I needed to know about developing using ASP.NET MVC and incorporating desing patterns and architectural styles with ASP.NET MVC, becuase after all,  ASP.NET MVC is just a UI design pattern and is not a panacea solution. 

    https://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/

    https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs

    <copied>

    An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.

    A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.

    In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.

    <end>

    A typical MVC controller I have seen developed, have developed or would develop is vastly different from what you have seen probably that is using a thin controller principle of no business logic or data access logic in the controller. 

    I didn't know how to arcutect either until someone introduced me to the Dofactory many  many years ago.

    https://www.dofactory.com/products/net-design-pattern-framework

     https://www.dofactory.com/net/design-patterns

    An example of a ASP.NET MVC controller, a thin controller.

    using Microsoft.AspNetCore.Mvc;
    using PublishingCompany.Models;
    
    namespace PublishingCompany.Controllers
    {
        public class AuthorController : Controller
        {
            private IAuthorDM adm;
            public AuthorController(IAuthorDM authorDM)
            {
                adm = authorDM;
            }
    
            public IActionResult Index()
            {
                return View(adm.GetAll());
            }
    
            public IActionResult Detail(int id = 0)
            {
                return id == 0 ? null : View(adm.Find(id));
            }
    
            public IActionResult Create()
            {
                return View(adm.Add());
            }
    
            [HttpPost]
            public ActionResult Create(AuthorVM.Author author, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                if (!ModelState.IsValid) return View(author);
    
                adm.Add(author);
                return RedirectToAction("Index");
            }
            
            public ActionResult Edit(int id = 0)
            {
                return id == 0 ? null : View(adm.Update(id));
            }
            
            [HttpPost]
            public ActionResult Edit(AuthorVM.Author author, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
                            
                if (!ModelState.IsValid) return View(author);
                           
                adm.Update(author);
                return RedirectToAction("Index");
            }
    public IActionResult Delete(int id = 0) { if (id > 0) adm.Delete(id); return RedirectToAction("Index"); } public ActionResult Cancel() { return RedirectToAction("Index", "Home"); } } }

    Wednesday, October 23, 2019 9:32 AM