European ASP.NET 4.5 Hosting BLOG

BLOG about ASP.NET 4, ASP.NET 4.5 Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European Entity Framework Hosting - UK :: Top 8 Reasons to use it in .Net Application

clock May 22, 2023 09:39 by author Peter

EF Core or Entity Framework Core is based upon the ORM or Object-Relational Mapper model. With the help of the ORM model, EF Core provides us with an intermediate layer between the domain model and the database objects. Microsoft treated EF Core as a data access-based API which helps us to communicate with the database by using .NET POCOs and Linq-type objects. While we use this Entity Framework in any application, it always takes less time to implement the CRUD-related layer with the database. In this section, we will mainly focus on the new features which are introduced in EF Core 7.0 version.

EF Core Architecture Design
Entity Framework Core or EF Core is a cross-platform-based, lightweight, and open-source version of our existing Entity Framework data access technology. In this architecture, we just need to focus on our programming code, and the rest operations related to the database handling are maintained by the EF Core itself. With the help of EF Core, we can perform many things like –

  • Can load data by using C# class objects or entities.
  • Can perform add, update, and delete operations by invoking related methods for those entities.
  • Can map multiple database table objects into a single C# entity objects.
  • Can handle the concurrent user scenario to update the same database table data.
  • Can use LINQ query to fetch data from the database.
  • Can establish a connection with different types of databases like SQL Server, SQLite, Azure Cosmos DB, PostgreSQL, etc.
  • Can build and develop our domain model based on any existing database.
  • Can maintain our database schema based on our domain model.

The below diagram represents the architecture structure behind the Entity Framework Core.


The DbContext is a special class that represents a unit of work and provides methods to configure options, connection strings, logging, and the model used to map your domain to the database. During the derive new classes from DbContext, it performs the following steps:
    Establish an active connection session with the database.
    Save and query instances of entities.
    Include properties of type DbSet<T> representing tables in the database.

In EF Core, the provider always translates the objects into the SQL Commands at the time of execution. We can treat EF Core as a Provider of Database.
    It Is a plug-in library designed for a specific database engine, such as SQL Server, Azure Cosmos DB, or PostgreSQL.
    Translates method calls and LINQ queries to the database's native SQL dialect.
    Extends EF Core to enable functionality that's unique to the database engine.

What’s new in EF Core 7.0?
When Microsoft introduced the new .Net Framework version 7.0, at the same time, they also introduced the new version of Entity Framework i.e. EF Core 7.0. EF Core 7.0 has many new features compared to the previous versions. Some of the major changes of EF Core in this new version are as below –
New Bulk Update and Bulk Delete Method

Before EF Core 7.0, we commonly use the SaveChanges method to perform save or update related operations in the database. This method normally identifies the changes in the entity objects and sends updated information to the database. So, in an earlier version of EF Core, if we want to update any record in the database, then first we need to query that record, make the changes in the result and then need to call the SaveChanges method. If we want to delete any records, we need to follow a similar workflow: retrieve the objects, change their state as deleted, and then call the SaveChanges.

Due to this workflow, for a long time, developers and community members request to bring some features quite similar to a LINQ query to directly push the changes into the database. So, in EF Core 7.0, Microsoft introduced two new methods, namely ExecuteUpdate and ExecuteDelete, for this purpose. Here, we need to remember that these two new method does not replace the SaveChanges method at all. These provide us with more flexibility while working with the database.

To delete any records, now, we can perform the code below –
context.Product.Where( s => s.ProductId == 100).ExecuteDelete();

Now, in the above example, we are deleting one single record. But in the same way, we can delete multiple records at a time by providing proper filter conditions in the LINQ expressions. And most importantly, this command will execute immediately and does not require invoking the SaveChanges method.

Just like the delete operation, we can perform the update operations as well. For that, we need to use the SetProperty method to assign the values of the change.
context.People
        .Where(p => p.City == "Calcutta")
        .ExecuteUpdate (s => s.SetProperty(c =>c.City, c =>"Kolkata"));


As per the above example, we are trying to update the people's city names from Calcutta to Kolkata. Executing this statement will update all records' city property values to a new property value in a single shot. While it executes the commands, it runs the below SQL commands in the database.
UPDATE [p]
SET [p].[City] = N'Kolkata'
FROM [People] AS [p]
WHERE [p].[City] = N'Calcutta'

SQL
Mapping JSON Type Column

In the case of a Database, using JSON Data type columns and storing data in that column is one of the most used and required features nowadays. By using this approach, we can store object-type data in a single column where we do not require a strict type relational concept.  Entity Framework Core 7, now provides support for this JSON-based column which helps us to map with .Net object types with JSON documents. Also, we can perform the LINQ queries based on these types of JSON columns along with save and update changes. Although, this feature is still in the basic mode as updated by the team. Probably, in the next release, such a more advanced implementation will be incorporated into this functionality.

During the implementation, the support we want to use the Employee class in which we will use another child object called AddressInfo as below.
public class Employee
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public int Age { get; set; }
    public Address AddressInfo { get; set; }
}

public class Address
{
    public string State { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string PostalCode { get; set; }
}

Now, related to the Entity Employee, we need to use two different mappings for the Employee.AddressInfo property in the OnModelling method. In this method, OwnsOne mapping provided an overload which help us to mention the relationship of the owned property by using OwnedNavigationBuilder.
modelBuilder.Entity<Employee>()
            .OwnsOne(p=> p.AddressInfo, jb => { jb.ToJson(); });


Performance Improvement on SaveChanges Method
In EF Core 6.0, one of the most important features was performance improvement for all types of non-tracking queries. At that time, the EF Core team promises that they will come up will more performance improvements in the next version i.e. EF Core 7. And now, they key their promise.  

In EF Core normal or default transaction process, when we invoke the SaveChanges method, then it is performed with a database transaction so that if one statement fails to execute, then the entire process will be rollback. But when we send only a command related to a single table to update or insert, then also this process is followed, which is unnecessary as there is no need to use Transaction for a single statement. Now, in EF Core 7, while we perform SaveChanges in one single entity, then EF Core sends only one command (DDL statement) despite sending send 3 commands (BEGIN Transaction, DDL statement, Commit Transaction) to the database. Due to this, the performance in EF Core is must faster.

Another change is made in the case of Insert Statement in EF Core 7. As we know, while we perform any insert operation in EF Core, it executes two statements in the database part, and that is Insert Statement paid with a  select statement to return the database generated value for any primary or foreign key. But now, in EF Core, the SQL Server makes compression on all of those commands to convert into a single command with the help of OUTPUT parameters in the insert statement.

SQL Command executed in EF Core 6.
INSERT INTO [Department] ([Name])
    VALUES (@p0);
    SELECT [DeptId]
    FROM [Department]
    WHERE @@ROWCOUNT = 1
    AND [DeptId] = scope_identity();

Now, in EF Core 7, SQL Command is executed.
INSERT INTO [Department] ([Name])
    OUTPUT INSERTED.[DeptId]
    VALUES (@p0);


Mapping Stored Procedure
In the conventional Entity Framework, we can use the stored procedures with the entities. So, we invoke the SaveChanges method, EF called the stored procedure by pushing into the parameters. But, in EF Core 7, this process makes much simpler. In EF Core 7 version, several FluentAPI-related methods have been introduced, like InsertUsingStoredProcedure, UpdateUsingStoredProcedure, and DeleteUsingStoredProcedure. These methods can be applied within an entity in the OnModelCreating method. Each of the above mention methods takes an input string as a procedure name and a StoredProcedureBuilder object which contains different parameters which need to be passed into the stored procedure.
modelBuilder.Entity<Person>()
    .InsertUsingStoredProcedure("uspPeopleInsert",
        spbuilder => spbuilder
            .HasParameter(p => p.PersonId, pb => pb.IsOutput().HasName("id"))
            .HasParameter(p => p.FirstName)
            .HasParameter(p => p.LastName)
)


Encrypt Defaults to True in SQL Server Connections
In EF Core 7, another breaking change is Encrypt value sets as true by default in the connection string. This is one of the breaking changes in Microsoft.Data.SqlClient packages. In the earlier version, the default value was Encrypt = false within the connection string. But now, in the latest version, this one is considered true by default. It means the Database server must be configured with a valid certificate, and the client must trust this certificate while establishing a connection with the server.
DB Context and API Enhancement

In EF Core 7.0, there are many small types of improvements done in the DBContext and its related classes. Some of them are as,
Now, uninitialized DbSet properties are automatically suppressed in EF Core 7. The default access type of the DbSet property is public. So, we use the DbSet property in the constructor, then it is automatically initialized by the DbContext.
Now, we can distinguish between the cancel the operation due to any hardware failure by using logs in the case of EF Core 7. This failure operation can be performed either by the application when it explicitly canceled any query or also by bypassing the CancellationToken passed to the operating methods.
Now, we can perform overloading against  IProperty and INavigation in EntityEntry methods on the model class.
We can use EntityEntry for any shared entity. In that case, EF Core will use the same CLR type for all different entity types. These are commonly called "shared-type entity types", and are treated as a dictionary type with the key/value pairs used for the properties of the entity type.

Model Binding
In EF Core 7.0, there are many small types of improvements done in the Model Binding. Some of them are as,
Indexes can be used as ascending or descending
    modelBuilder
        .Entity<Post>()
        .HasIndex(post => post.Title)
        .IsDescending();

    modelBuilder
        .Entity<Blog>()
        .HasIndex(blog => new { blog.Name, blog.Owner })
        .IsDescending(false, true);


    Can map composite key-related attribute
    [PrimaryKey(nameof(PostId), nameof(CommentId))]
    public class Comment
    {
        public int PostId { get; set; }
        public int CommentId { get; set; }
        public string CommentText { get; set; } = null!;
    }


Can define the delete behavior as the mapping attribute for the relationship data. The default attribute value is DeleteBehaviour.Cascade. But that value can be changed to DeleteBehavior.NoAction.
    public class Post
    {
        public int Id { get; set; }
        public string? Title { get; set; }

        [DeleteBehavior(DeleteBehavior.NoAction)]
        public Blog Blog { get; set; } = null!;
    }

Improved Code value generation
EF7 provides two significant improvements to the automatic generation of values for key field properties. In EF Core 7, key types based on value converters can use automatically generated key values so long as the underlying type supports this. This is configured in the normal way using ValueGeneratedOnAdd. EF7 also introduces support for a database sequence attached to the key's column default constraint. In its simplest form, this just requires telling EF Core to use a sequence for the key property



European ASP.NET 4.5 Hosting - UK :: How to Improve Your Entity Framework Performance

clock November 23, 2015 23:46 by author Scott

LINQ to Entity is a great ORM for querying and managing databases. There are some points that we should consider while designing and querying databases using the Entity Framework ORM.

Disable change tracking for entity if not needed

In the Entity Framework, the context is responsible for tracking changes in entity objects. Whenever we are only reading data, there is no need to track the entity object. We can disable entity tracking using the MergeOption, as in:

AdventureWorksEntities e = new AdventureWorksEntities();
e.EmployeeMasters.MergeOption = System.Data.Objects.MergeOption.NoTracking;

Use Pre-Generating Views to reduce response time for the first request

While working with Entity Framework, view generation may take longer for a large and complicated model. We can use a pre-generated view to save run time cost to generate a view for the first request of a page. A Model Generated view helps us to improve start-up performance at run time.

Avoid fetching all the fields if not required

Avoid fetching all fields from the database that are not really required. For example we have an EmployeeMaster table and for some operation I require only the EmployeeCode field so the query must be:

AdventureWorksEntities e = new AdventureWorksEntities();
string
 code = e.EmployeeMasters.Where(g => g.EmployeeId == 1000)
                                                             .Select(s => s.EmployeeCode).FirstOrDefault();

Retrieve only required number of records (rows)

Do not collect all data while binding data to a data grid. For example if we have a data grid on a page and we only show 10 records on the screen, so do not fetch all records from the database, as in:

AdventureWorksEntities e = new AdventureWorksEntities();
int
 pageSize = 30, startingPageIndex = 3;
List<EmployeeMaster> lstemp = e.EmployeeMasters
                                                           .Take(pageSize)
                                                           .Skip(startingPageIndex * pageSize).ToList();

Avoid using Contains

Avoid use of the contain keyword with a LINQ - Entity Query. While Entity Framework generates equivalent SQL, the contain is converted in the "WHERE IN" clause. The "IN" clause has performance issues.

Avoid using Views

Views degrade the LINQ query performance. So avoid using views in LINQ to Entities.

Use Compiled Query

If you are using Entity Framework 4.1 and below, you must use a compiled query. The Compiled Query class provides compilation and caching of queries for reuse. The Entity Framework 5.0 supports a new feature called Auto-Compiled LINQ Queries. With EF 5.0, LINQ to Entity queries are compiled automatically and placed in EF's query cache, when executed.

static Func<AdventureWorksEntitiesIQueryable<EmployeeDetail>> getEmpList = (
            CompiledQuery.Compile((AdventureWorksEntities db) =>
                db.EmployeeDetails
            ));

AdventureWorksEntities e = new AdventureWorksEntities1();
List
<EmployeeDetail> empList = getEmpList(e).ToList();

Must examine Queries before being sent to the Database

When we are investigating performance issues, sometimes it's helpful to know the exact SQL command text that the Entity Framework is sending to the database. I would suggest that we must examine each and every LINQ to Entity queries to avoiding performance issues.

Efficiently Loading Related Data

Entity Framework supports the loading of related data. The Include method helps us load relevant data. Use of the Include method ensures it is really required for the page i.e. do not include a navigation property whenever it is not really required.

Select appropriate Loading type while defining model

Entity Framework supports three ways to load related data: eager loading, lazy loading and explicit loading. Eager loading is the process in which a query of one type of entity also loads related entities as part of the query. Eager loading is done by use of the Include method. Lazy loading is the process in which an entity or collection of entities is automatically loaded from the database the first time that a property referring to the entity/entities is accessed. When lazy loading disabled, it is possible to lazily load related entities with use of the Load method on the related entity's entry. It is called explicit loading. So depending upon on the type of application and requirement we can select appropriate Loading type for the entity model.

Conclusion

Using the above definition tips, we can definitely improve the performance of LINQ to Entity Queries.



European Entity Framework Hosting - UK :: Introduction about Entity Framework 5 and Implement it on MVC

clock August 5, 2015 09:47 by author Scott

In this article, we will introduce the Entity Framework 5.0 Code First approach in MVC applications. The ADO.NET Entity Framework is an Object Relational Mapper (ORM) included with the .NET framework. It basically generates business objects and entities according to the database tables. It provides basic CRUD operations, easily managing relationships among entities with the ability to have an inheritance relationship among entities.

When using the EF we interact with an entity model instead of the application's relational database model. This abstraction allows us to focus on business behavior and the relationships among entities. We use the Entity Framework data context to perform queries. When one of the CRUD operations is invoked, the Entity Framework will generate the necessary SQL to perform the operation.

How to Implement

To create this application we should have a basic knowledge of the DbContext class of theSystem.Data.Entity namespace. We should also be familiar with views because in this article I am not describing views for each action method so you can create a view according to action methods or you can scaffold templates to create a view for Edit, List, Create, Delete and Details.

We need to install the Entity Framework Nuget package in our application. When we install the Entity Framework Nuget package, two references (System.Data.Entity and EntityFramework) are added to our application. Thereafter we can perform CRUD operations using Entity Framework.

How to Use Entity Framework

Whether you have an existing database or not, you can code your own classes and properties (aka Plain Old CLR Objects, or POCOs) that correspond to tables and columns and use them with the Entity Framework without an .edmx file. In this approach the Entity Framework does not leverage any kind of configuration file (.edmx file) to store the database schema, because the mapping API uses these conventions to generate the database schema dynamically at runtime. Currently, the Entity Framework Code First approach does not support mapping to Stored Procedures. The ExecuteSqlCommand() and SqlQuery() methods can be used to execute Stored Procedures.

To understand the Entity Framework Code First Approach, you need to create an MVC application that has two entities, one is Publisher and another is Book. So let's see an example step-by-step. To create your MVC Application, in Visual Studio select "File" -> "New" -> "Project..." then select "MVC 4 Application" then select "Empty Application".

1. Create Modal Classes

We create classes for Publisher and Book under the Models folder, those classes are used as entities and an entities set. These classes will have mapping with a database because we are using the code first approach and these classes will create a table in a database using the DbContext class of Entity Framework. So let's see these classes one by one.
The Publisher class is in the Models folder; that file name is Publisher.cs as in the following:
using System.Collections.Generic;
namespace ExampleCodeFirstApproch.Models
{
    public class Publisher
    {
        public int PublisherId { get; set; }
        public string PublisherName { get; set; }
        public string Address { get; set; }
        public ICollection<book> Books { get; set; }
    }
}</book>


The Book class is in the Models folder; that file name is Book.cs as in the following:

namespace
ExampleCodeFirstApproch.Models

{
    public class Book
    {
        public int BookId { get; set; }
        public string Title { get; set; }
        public string Year { get; set; }
        public int PublisherId { get; set; }
        public Publisher Publisher { get; set; }
    }
}


2. Create Data Access Layer
This part of the article is the heart of the article as well as the code first approach. First of all we need a connection string so we can connect with our database by application. We create a connection in the web.configfile. I provide the connection string name as DbConnectionString, you are free to give any name to it but remember it because we will use it in our context class.

<connectionStrings>
   
<add name="DbConnectionString"
     
connectionString="Data Source=steve-PC;Initial Catalog=CodeFirst;User ID=sa;
      Password=*******" providerName="System.Data.SqlClient" />
</connectionStrings>

We have both classes, Publisher and Book, so now we will create a context class. We create aLibraryContext class under the Models folder, that file name is LibraryContext.cs. This class inherits DbContextso we can use the DbContext class methods using a LibraryContext class object as in the following:
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace ExampleCodeFirstApproch.Models
{
    public class LibraryContext :DbContext
    {
        public LibraryContext()
            : base("name=DbConnectionString")
        {
        }
        public DbSet<Publisher> Publishers { get; set; }
        public DbSet<Book> Books { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {                     
            modelBuilder.Entity<Publisher>().HasKey(p => p.PublisherId);
            modelBuilder.Entity<Publisher>().Property(c => c.PublisherId)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);           
            modelBuilder.Entity<Book>().HasKey(b => b.BookId);
            modelBuilder.Entity<Book>().Property(b => b.BookId)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);           
            modelBuilder.Entity<Book>().HasRequired(p => p.Publisher)
                .WithMany(b => b.Books).HasForeignKey(b=>b.PublisherId);           
            base.OnModelCreating(modelBuilder);
        }
    }
}

Our LibraryContext class that inherits the DbContext class is ready. The LibraryContext class has a three-part constructor, DbSet properties, and an OnModelCreating method. Let's see each one by one.

Constructor: It is an empty constructor that doesn't have any parameters, in other words it is the default constructor but it inherits the base class single string parameterized constructor. This constructor constructs a new context instance using the given string as the name (as we used) or the connection string for the database to which a connection will be made. Here DbConnectionString is the name of the connection string defined in the web.config file of the application.

public LibraryContext(): base("name=DbConnectionString")
{
}

Property: When developing with the Code First workflow you define a derived DbContext that represents the session with the database and exposes a DbSet for each type in your model. The common case shown in the Code First examples is to have a DbContext with public automatic DbSet properties for the entity types of your model.
public DbSet<Publisher> Publishers { get; set; }
public DbSet<Book> Books { get; set; }


The Dbset property represents an entity set used to perform create, read, update, and delete operations. A non-generic version of DbSet<TEntity> can be used when the type of entity is not known at build time. Here we are using the plural name of the property for an entity, that means your table will be created with this name in the database for that specific entity.

Method: The LibraryContext class has an override OnModelCreating method. This method is called when the model for a derived context has been initialized, but before the model has been locked down and used to initialize the context. The default implementation of this method does nothing, but it can be overridden in a derived class such that the model can be further configured before it is locked down. Basically in this method we configure the database table that will be created by a model or a defined relationship among those tables.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{  
   modelBuilder.Entity<Publisher>().HasKey(p => p.PublisherId);
   modelBuilder.Entity<Publisher>().Property(c => c.PublisherId)
          .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
   modelBuilder.Entity<Book>().HasKey(b => b.BookId);
   modelBuilder.Entity<Book>().Property(b => b.BookId)
         .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
   modelBuilder.Entity<Book>().HasRequired(p => p.Publisher)
         .WithMany(b => b.Books).HasForeignKey(b=>b.PublisherId);
   base.OnModelCreating(modelBuilder);
}

This method accepts one parameter, an object of DbModelBuilder. This DbModelBuilder class maps POCO classes to database schema. This method is called only once when the first instance of a derived context is created. The model for that context is then cached and is for all further instances of the context in the app domain. This caching can be disabled by setting the ModelCaching property on the given ModelBuidler, but this can seriously degrade performance. More control over caching is provided through use of theDbModelBuilder and DbContext classes directly.

Configure/Mapping Properties with the Fluent API
The OnModelCreating() method under the LibraryContext class uses the Fluent API to map and configure properties in the table. So let's see each method used in the OnModelCreating() method one by one.

modelBuilder.Entity<Book>().HasRequired(p => p.Publisher)
.WithMany(b => b.Books).HasForeignKey(b=>b.PublisherId);

3. Create Controller for CRUD Operations

Now we create two controllers, one for Publisher CRUD operations (PublisherController.cs) and another for Book CRUD operations (BookController.cs) under the Controllers folder in the application. So here is the code for each.

The Publisher controller in the file PublisherController.cs in the Controllers folder:
using System.Linq;
using System.Web.Mvc;
using ExampleCodeFirstApproch.Models;
namespace ExampleCodeFirstApproch.Controllers
{
    public class PublisherController : Controller
    {
        LibraryContext objContext;
        public PublisherController()
        {
            objContext = new LibraryContext();
        }
        #region List and Details Publisher
        public ActionResult Index()
        {
            var publishers = objContext.Publishers.ToList();
            return View(publishers);
        }
        public ViewResult Details(int id)
        {
            Publisher publisher =
              objContext.Publishers.Where(x=>x.PublisherId==id).SingleOrDefault();
            return View(publisher);
        }
        #endregion
        #region Create Publisher
        public ActionResult Create()
        {
            return View(new Publisher());
        }
        [HttpPost]
        public ActionResult Create(Publisher publish)
        {
            objContext.Publishers.Add(publish);
            objContext.SaveChanges();
            return RedirectToAction("Index");
        }
        #endregion
        #region edit publisher
        public ActionResult Edit(int id)
        {
            Publisher publisher = objContext.Publishers.Where(
              x => x.PublisherId == id).SingleOrDefault();
            return View(publisher);
        }
        [HttpPost]
        public ActionResult Edit(Publisher model)
        {
            Publisher publisher = objContext.Publishers.Where(
              x => x.PublisherId == model.PublisherId).SingleOrDefault();
            if (publisher != null)
            {
                objContext.Entry(publisher).CurrentValues.SetValues(model);
                objContext.SaveChanges();
                return RedirectToAction("Index");
            }             
            return View(model);
        }
       #endregion
        #region Delete Publisher
        public ActionResult Delete(int id)
        {
            Publisher publisher = objContext.Publishers.Find(id);
            //.Where(x => x.PublisherId == id).SingleOrDefault();

            return View(publisher);
        }
        [HttpPost]
        public ActionResult Delete(int id, Publisher model)
        {
           var publisher =
             objContext.Publishers.Where(x => x.PublisherId == id).SingleOrDefault();
           if (publisher != null)
            {
                objContext.Publishers.Remove(publisher);
                objContext.SaveChanges();
            }
            return RedirectToAction("Index");
        }
        #endregion
    }
}

The Book controller in the file BookController.cs in the Controllers folder:
using
System.Linq;
using System.Web.Mvc;
using ExampleCodeFirstApproch.Models;
namespace ExampleCodeFirstApproch.Controllers
{
    public class BookController : Controller
    {
       LibraryContext objContext;
       public BookController()
        {
            objContext = new LibraryContext();
        }
        #region List and Details Book
        public ActionResult Index()
        {
            var books = objContext.Books.ToList();
            return View(books);
        }
        public ViewResult Details(int id)
        {
            Book book = objContext.Books.Where(x=>x.BookId==id).SingleOrDefault();
            return View(book);
        }
        #endregion
        #region Create Publisher
        public ActionResult Create()
        {
            return View(new Book());
        }
        [HttpPost]
        public ActionResult Create(Book book)
        {
            objContext.Books.Add(book);
            objContext.SaveChanges();
            return RedirectToAction("Index");
        }
        #endregion
        #region Edit Book
        public ActionResult Edit(int id)
        {
            Book book = objContext.Books.Where(x => x.BookId == id).SingleOrDefault();
            return View(book);
        } 
        [HttpPost]
        public ActionResult Edit(Book model)
        {
            Book book = objContext.Books.Where(x => x.BookId == model.BookId).SingleOrDefault();
            if (book != null)
            {
                objContext.Entry(book).CurrentValues.SetValues(model);
                objContext.SaveChanges();
                return RedirectToAction("Index");
            }             
            return View(model);
        }
       #endregion
        #region Delete Book
        public ActionResult Delete(int id)
        {
            Book book = objContext.Books.Find(id);
            return View(book);
        }
        [HttpPost]
        public ActionResult Delete(int id, Publisher model)
        {
           var book = objContext.Books.Where(x => x.BookId == id).SingleOrDefault();
           if (book != null)
            {
                objContext.Books.Remove(book);
                objContext.SaveChanges();
            }
            return RedirectToAction("Index");
        }
        #endregion
    }
}


Both Publisher and Book controllers are ready and create a view according to the action method using a scaffold template and you can download a zip folder. Run the application and you get that your tables are created in the database with a relationship.



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in