Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Monday, November 18, 2019

Entity Framework Core - Add, Remove, Attach and Update


In this post I will explain how the Add / Remove / Attach and Update affects the EntityState and how Entiy Framework behaves based on each state.

Before we start talking about the differences of each of the methods above is important to understand the five different states defined by Entity Framework.

Entity states

These states are defined in the EntityState Enum, see below the description of each one:

  • Added: the entity is being tracked by the context but does not yet exist in the database
  • Unchanged: the entity is being tracked by the context and exists in the database, and its property values have not changed from the values in the database
  • Modified: the entity is being tracked by the context and exists in the database, and some or all of its property values have been modified
  • Deleted: the entity is being tracked by the context and exists in the database, but has been marked for deletion from the database the next time SaveChanges is called
  • Detached: the entity is not being tracked by the context


SaveChanges

The SaveChanges method will work in different ways based on the EntityState.
See below the behavior for each EntityState:

  • Unchanged entities are not touched by SaveChanges. Updates are not sent to the database for entities in the Unchanged state.
  • Added entities are inserted into the database and then become Unchanged when SaveChanges returns.
  • Modified entities are updated in the database and then become Unchanged when SaveChanges returns.
  • Deleted entities are deleted from the database and are then detached from the context.


Add, Remove, Attach and Update

Now that we now the Entity Framework EntityStates and how the SaveChanges work with each state will be easy to understand how the methods Add / Remove / Attach and Update works.

Add

The Add method will add the object to the context, which means that the object will start being tracked by Entity Framework and its Entity State will be EntityState.Added.
Once SaveChanges is called a new record will be added to the database.

See below the Entity State in the Immediate Window:


Attach

The Attach method will add the object to the context, which means that the object will start being tracked by Entity Framework and its Entity State will be EntityState.Unchanged.
Once SaveChanges is called  Entity framework won`t touch this object.


See below the Entity State in the Immediate Window:


Remove

The Remove method will add the object to the context, which means that the object will start being tracked by Entity Framework and its Entity State will be EntityState.Removed.
Once SaveChanges is called  Entity framework will delete the record from the database.


See below the Entity State in the Immediate Window:

Update

The Update method will add the object to the context, which means that the object will start being tracked by Entity Framework and its Entity State will be EntityState.Modified.
Once SaveChanges is called, Entity framework will update the record in the database.


See below the Entity State in the Immediate Window:


Conclusion

As we can see all the four methods above will tell Entity Framework to start tracking the objects, but each of them will set different States to the entity and then Entity framework will execute a different operation in the database when SaveChanges is called.

Friday, November 15, 2019

Understanding ASP.NET Middleware


In ASP.NET Core, middleware is the term used for components that form the Request Pipeline.
The pipeline request is like a chain, which can contain multiple middlewares. These components will handle the request in sequence; each component will inspect the request and decide whether it should be passed to the next middleware or just generate a response interrupting the chain.
Once the request has been handled a response will be generated and send back to the client passing along the chain.

Execution Order

Middlewares will execute in the same order they are registered when handling requests and in the reverse order when handling responses.

Check the example below:


How to create a Middleware

Middleware components don`t implement interfaces or derive from classes, It simply has a constructor that takes RequestDelegate as parameter and implements the Invoke Method.

The RequestDelegate represents the next Middleware component of the chain and the Invoke method is called when the component receives a request.

Next I will show a few examples.

Creating Content-Generating Middleware

The most important type of middleware generates content for clients, and it is this category to which MVC belongs.

This kind of middleware is used when you want to generate some content and send it back to the client without the need of dealing with all the MVC complexity.

Check the implementation below:

    public class ContentMiddleware
    {
        private RequestDelegate nextDelegate;
        public ContentMiddleware(RequestDelegate next) => nextDelegate = next;
        public async Task Invoke(HttpContext httpContext)
        {
            if (httpContext.Request.Path.ToString().ToLower() == "/content-middleware")
            {
                await httpContext.Response.WriteAsync(
                "This content was generated by the middleware", Encoding.UTF8);
            }
            else
            {
                await nextDelegate.Invoke(httpContext);
            }
        }
    }

Creating Short-Circuiting Middleware

Short-Circuiting Middleware Components are used when you want to inspect the request and decide if the request should be passed to next component or not.

The example below is checking if it the request contains the User-Id header, if not the middleware will break the chain and return a 401-Unauthorized response to the client.

    public class ShortCircuitMiddleware
    {
        private RequestDelegate nextDelegate;
        public ShortCircuitMiddleware(RequestDelegate next) => nextDelegate = next;
        public async Task Invoke(HttpContext httpContext)
        {
            if (!httpContext.Request.Headers["User-Id"].Any())
            {
                httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            }
            else
            {
                await nextDelegate.Invoke(httpContext);
            }
        }
    }

Creating Request-Editing Middleware

The next type of middleware component examined doesn’t generate a response. Instead, it changes requests before they reach other components later in the chain. This kind of middleware is mainly used for platform integration to enrich the ASP.NET Core representation of an HTTP request with platform-specific features.

The example below will check if the request contains a blank User-Id in the header and if yes it will be removed.
 public async Task Invoke(HttpContext httpContext)
        {

            if (httpContext.Request.Headers["User-Id"].Any() &&
                string.IsNullOrWhiteSpace(httpContext.Request.Headers["User-Id"].ToString()))
            {
                httpContext.Request.Headers.Remove("User-Id");
            }
            else
            {
                await nextDelegate.Invoke(httpContext);
            }
        }

Interacting with another Middleware

Middleware components can interact with each other, let`s consider that RequestEditMiddleware is executed before the ShortCircuitMiddleware.

In that case if a request contains blank User-Id Header the RequestEditMiddleware will remove that header from the request and call the next component, which is the ShortCircuitMiddleware, the ShortCircuitMiddleware won`t find the header User-Id and will break the chain returning a 401 response to the client.

Registering a Middleware

Now that we already know how to create our own custom components, how do we use it?
It`s simple, in the Startup class there is a method called Configured which is responsible to setup how the application will handle requests.

This method has a parameter of type IApplicationBuilder, that is the object we use to register our components.
See example below:

       public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseMiddleware<ContentMiddleware>();
            app.UseMiddleware<RequestEditMiddleware>();
            app.UseMiddleware<ShortCircuitMiddleware>();
            app.UseHttpsRedirection();
            app.UseMvc();
        }

There is a more elegant way to register the components, for that we need to create some extension methods.

See below:

  public static class MiddlewareExtensions
    {
        public static IApplicationBuilder UseContentMiddleware(this IApplicationBuilder app)
        {
            return app.UseMiddleware<ContentMiddleware>();
        }
        public static IApplicationBuilder UseRequestEditMiddleware(this IApplicationBuilder app)
        {
            return app.UseMiddleware<RequestEditMiddleware>();
        }
        public static IApplicationBuilder UseShortCircuitMiddleware(this IApplicationBuilder app)
        {
            return app.UseMiddleware<ShortCircuitMiddleware>();
        }
    }

After creating the extension methods all we have to do is register the components using it.

public void ConfigureDevelopment(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseContentMiddleware();
            app.UseRequestEditMiddleware();
            app.UseShortCircuitMiddleware();
            app.UseHttpsRedirection();
            app.UseMvc();
        }

Microservices – Creating Resilient Services

Dealing with unexpected failures is one of the hardest problems to solve, especially in a distributed system . A microservice needs to...