Create table in Database using Entity Framework - c#

I'm trying to link my MVC project with a database using Entity Framework, but I can't figure out how to store new records to a database. So far I have the following code:
//model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using MvcApplication1.Controllers;
namespace MvcApplication1.Models
{
public class CarUser
{
public int ID { get; set; }
[DisplayName ("First Name")]
public string Fname { get; set; }
[DisplayName ("Surname")]
public string Sname { get; set; }
}
}
//controller
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class CarUserController : Controller
{
private FormDataContext db = new FormDataContext();
//
// GET: /CarUser/
public ActionResult Index()
{
return View(db.CarUsers.ToList());
}
//
// GET: /CarUser/Details/5
public ActionResult Details(int id = 0)
{
CarUser caruser = db.CarUsers.Find(id);
if (caruser == null)
{
return HttpNotFound();
}
return View(caruser);
}
//
// GET: /CarUser/Create
public ActionResult Create()
{
return View();
}
//
// POST: /CarUser/Create
[HttpPost]
public ActionResult Create(CarUser caruser)
{
if (ModelState.IsValid)
{
db.CarUsers.Add(caruser);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(caruser);
}
//
// GET: /CarUser/Edit/5
public ActionResult Edit(int id = 0)
{
CarUser caruser = db.CarUsers.Find(id);
if (caruser == null)
{
return HttpNotFound();
}
return View(caruser);
}
//
// POST: /CarUser/Edit/5
[HttpPost]
public ActionResult Edit(CarUser caruser)
{
if (ModelState.IsValid)
{
db.Entry(caruser).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(caruser);
}
//
// GET: /CarUser/Delete/5
public ActionResult Delete(int id = 0)
{
CarUser caruser = db.CarUsers.Find(id);
if (caruser == null)
{
return HttpNotFound();
}
return View(caruser);
}
//
// POST: /CarUser/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
CarUser caruser = db.CarUsers.Find(id);
db.CarUsers.Remove(caruser);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}
//formdatacontext
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace MvcApplication1.Models
{
public class FormDataContext : DbContext
{
public DbSet<CarUser> CarUsers
{ get; set; }
}
}
//formdatainitialiser
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.IO;
namespace MvcApplication1.Models
{
public class FormDataInitializer : DropCreateDatabaseAlways<FormDataContext>
{
protected override void Seed(FormDataContext context)
{
base.Seed(context);
var CarUsers = new List<CarUser>
{
new CarUser {
ID = 1,
Fname = "Craig",
Sname = "Higginson",
}
};
CarUsers.ForEach(s => context.CarUsers.Add(s));
context.SaveChanges();
}
}
}
I've also got the following in my web.config file
<connectionStrings>
<add name="FormDataContext"
connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=FormData.mdf;Integrated Security=True" providerName="System.Data.SqlClient" />
This all builds fine, and when I navigate to /caruser i am able to create new records. These records aren't being stored in my database.
Do I need to create the table in the database first or should Entity Framework create this for me, if i have referenced the database correctly?

If you're using a Code First approach then Entity Framework will build the table for you. It looks like you are not using Code First, so you will have create the table in the database. I assume you're using an Entity Data Model (.edmx)? If so, you will create your table in the database, then update your data model (.edmx). If you have not yet created your .edmx file, you need to do that - the .edmx file will contain all your CRUD operations.
What I'm confused about is I'd imagine your code would throw an error if the table did not exist (i.e. if the table represented by your data model didn't map to an actual table in the database, because it doesn't exist). So, the question is, does your table already exist? If it does, then step through the code line by line to find out why your records aren't being saved. If it doesn't exist, then add the table via SQL Server Management Studio (or similar), then open your .edmx file, right click on the layout that comes up, click "Update Model from database".

You can find all needed info here:
creating-an-entity-framework-data-model-for-an-asp-net-mvc-application

First you have add an edmx project to your existing solution which is a mockup of db and contains all the tables and SPs.
From your action method make a call to one more class, say DataAccessLayer.cs.
In DataAccessLayer.cs, add a reference to your edmx project.
Use this code:
using (var entity = new FormDataContext())
{
//entity. will give you all the tables in the database.
}

Related

Web Api Repository/ValueController problem

I develop web application. I started from Web Api with Entity Framework. I want realize CRUD function.
Read function works fine
But problem with Create, Update, Delete, could you check it and tell me, what I do wrong?
I attach 2 blocks of code, I don't know how I can realize 1st repository (Mistake in C,U,D - function) in controller.
I don't have enough experience with web api, could you tell me, how I need setting Repository(only for realize create, delete, update) file and after realize it in Value Controller
I need your advice about create, update, delete - function
Customer Repos
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace WebAPI
{
public class CustomerRepository
{
public IQueryable<Customer> GetAllCustomers()
{
DevelopersEntities dev = new DevelopersEntities();
return dev.Customers;
}
public IQueryable<Customer> GetAllCustomers(int id)
{
DevelopersEntities dev = new DevelopersEntities();
return dev.Customers.Where(c=>c.Id==id).Select(e=>e);
}
public IQueryable<Customer> DeleteCustomer(int id)
{
DevelopersEntities dev = new DevelopersEntities();
var cus = dev.Customers.Where(s => s.Id == id).FirstOrDefault();
dev.Entry(cus).State = System.Data.Entity.EntityState.Deleted;
dev.SaveChanges();
return cus;
}
}
public IQueryable<Customer> CreateCustomer(Customer customer)
{
DevelopersEntities dev = new DevelopersEntities();
dev.Customers.Add(new Customer()
{
Id = customer.Id,
Name = customer.Name
});
dev.SaveChanges();
return Ok();
}
public IQueryable<Customer> UpdateCustomer(Customer customer)
{
DevelopersEntities dev = new DevelopersEntities();
var cus = dev.Customers.Where(s => s.Id == customer.Id).FirstOrDefault();
cus.Id = customer.Id;
cus.Name = customer.Name;
dev.SaveChanges();
return Ok();
}
}
Values Controller
using DevelopersWeb.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebAPI;
namespace DevelopersWeb.Controllers
{
public class ValuesController : ApiController
{
ModelFactory _modelFactory;
public ValuesController()
{
_modelFactory = new ModelFactory();
}
// GET api/values
public IEnumerable<CustomerModel> Get()
{
CustomerRepository cr = new CustomerRepository();
return cr.GetAllCustomers().ToList().Select(c=> _modelFactory.Create(c));
}
// GET api/values/5
public string Get(int id)
{
return "xxx";
}
// POST api/values
public void Post([FromBody] CustomerModel customerModel)
{
CustomerRepository cr = new CustomerRepository();
cr.CreateCusomer(customer);
return Ok();
}
// PUT api/values/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
}

Unable to resolve service for type while attempting to activate a service in startup.cs

Have spent way too much time trying to figure this out. Thanks for any help. .Net Core 3.1 trying to register a service in Startup.cs
Error CS0311: The type 'Apex.UI.MVC.ProjectService' cannot be used as type parameter 'TImplementation' in the generic type or method ServiceCollectionServiceExtensions.AddScoped<TService, TImplementation>(IServiceCollection). There is no implicit reference conversion from 'Apex.UI.MVC.ProjectService' to 'Apex.EF.Data.IProjects'. (CS0311) (Apex.UI.MVC)
services.AddScoped<IProjects, ProjectService>();
using System;
using Apex.EF.Data;
using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;
using System.Linq;
using Apex.UI.MVC.Models.Projects;
namespace Apex.UI.MVC.Controllers
{
public class ProjectController : Controller
{
private IProjects _projects;
public ProjectController(IProjects projects)
{
_projects = projects;
}
public IActionResult Index()
{
var projectModels = _projects.GetAll();
var listingResult = projectModels
.Select(result => new ProjectIndexListingModel
{
Id = result.Id,
ProjectName = result.ProjectName,
ProjectImage = result.ProjectImage
});
var model = new ProjectIndexModel()
{
Project = listingResult
};
return View(model);
}
}
}
using System;
using System.Collections.Generic;
using Apex.EF.Data;
using Apex.EF.Data.Models;
namespace Apex.EF.Data
{
public interface IProjects
{
IEnumerable<Project> GetAll();
Project GetById(int id);
void Add(Project newProject);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using Apex.EF.Data;
using Apex.EF.Data.Models;
using Microsoft.EntityFrameworkCore;
namespace ApexServices
{
public class ProjectService : IProjects
{
private ApexContext _context;
public ProjectService(ApexContext context)
{
_context = context;
}
public void Add(Project newProject)
{
_context.Add(newProject);
_context.SaveChanges();
}
public IEnumerable<Project> GetAll()
{
return _context.Projects
.Include(project => project.Status.IsInShop == true);
}
public Project GetById(int id)
{
return _context.Projects
.Include(project => project.Status.IsInShop==true)
.FirstOrDefault(project => project.Id == id);
}
}
}
The namespaces shown in the exception are different to the example code shown. There are probably conflicting types in the project (not shown).
If that is really the case, then include the full namespace when registering the type with the container to avoid conflicts.
Based on the shown code, that would be
services.AddScoped<IProjects, ApexServices.ProjectService>();

NET MVC 5: Update only one field in the Database

I want to update only one filed of the DB. I am creating a function in my Controller (AOProf Controller) that looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Accommodation_App.Models;
using System.Data.Entity;
namespace Accommodation_App.Controllers
{
public class AOProfController : Controller
{
private StudAccommodationEntities1 SContextUser;
private DbSet<User> UserDb;
private StudAccommodationEntities1Entities SContextProp;
private DbSet<Property> Properties;
public AOProfController()
{
SContextUser = new StudAccommodationEntities1();
UserDb = SContextUser.UserDb;
SContextProp = new StudAccommodationEntities1Entities();
Properties = SContextProp.Properties;
}
[HttpPost]
public ActionResult Reject(int id)
{
Property obj = Properties.Find(id);
if (obj != null)
{
obj.isApproved = false;
UpdateModel(obj);
SContextProp.SaveChanges();
}
else{
return Content("Not such an object");
}
return Content("the rejected is confirmed");
}
And in my view I call this function from the onclick event. I sent the param before to the view. It is send correctly.
<button value="Reject" onclick="location.href='#Url.Action("Reject", "AOProf", new { id = item.ProId })'" >Reject</button>
The url that appears in the URL bar after clicking the button is
http://localhost:54464/AOProf/Reject/1
It looks fine, but the record won't update in the database. It will stay the same. Can you please, help me to understand how to to do it the right way?

c# mvc viewmodel database first unable to create view

I am an experienced programmer but relatively new to c# mvc. I am attempting to create my first viewmodel to combine two models into one so a view can access members from both. I have followed instructions on combining distinct models into one view model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ViApplication.Models;
using System.ComponentModel.DataAnnotations;
namespace ViApplication.ViewModel
{
public class TemplateMTMQuestionViewModel
{
public TemplateVISpdat ThisTemplate { get; set; }
public MtmTemplateViSpdatQuestion ThisMTMQuestion { get; set; }
}
}
I have created a controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ViApplication.ViewModel;
using ViApplication.Models;
using System.Net;
namespace ViApplication.Controllers
{
public class TemplatesMTMQuestions : Controller
{
private VulnerabilityIndexDatabaseEntities db = new VulnerabilityIndexDatabaseEntities();
public ActionResult AddQuestionToTemplate(long? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
TemplateVISpdat templateVISpdat = GetTemplateByID(id);
if (templateVISpdat == null)
{
return HttpNotFound();
}
TemplateMTMQuestionViewModel TMTMQVM = new TemplateMTMQuestionViewModel();
TMTMQVM.ThisTemplate = GetTemplateByID(id);
TMTMQVM.ThisMTMQuestion = GetBlankMtmTemplateViSpdatQuestion();
return View(TMTMQVM);
}
public TemplateVISpdat GetTemplateByID(long? id)
{
TemplateVISpdat templateVISpdat = db.TemplateVISpdats.Find(id);
return templateVISpdat;
}
public MtmTemplateViSpdatQuestion GetBlankMtmTemplateViSpdatQuestion()
{
MtmTemplateViSpdatQuestion TMTMQVM = new MtmTemplateViSpdatQuestion();
return TMTMQVM;
}
}
}
This compiles fine. But when I try to create a view from AddQuestionToTemplate and select Empty and my ViewModel I get:
Unable to retrieve metadata for
ViApplication.ViewMdoel.TemplateMTMQuestionViewModel. One or more
validation errors were detected during model generation.
TemplateMTMQuestionViewModel::EntityType TemplateMTMQuestionViewModel
has no key defined
The only difference between this project and other projects is that I am using database first.
Any help would be greatly appreciated.

Azure mobile service - accessing a table controller from another custom controller

I am trying to access a table using its controller from another controller method.
But when the method tries to call the table controller method I get an exception:
Exception=System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.WindowsAzure.Mobile.Service.TableController.....
I manage to access the table controller method from the web API and execute it successfully.
I tried the same thing with TodoItem given as an example by the initial mobile service.
After several publishes to the server trying to fix the issue the web API stopped working and I get this exception : An exception of type 'Microsoft.WindowsAzure.MobileServices.MobileServiceInvalidOperationException' occurred in mscorlib.dll but was not handled in user code
Additional information: The request could not be completed. (Internal Server Error) I managed to solve it when I reopened a mobile service and database with the exact same code that didn't work.
Any tips ?
Here is my table controller created by the controller wizard:
using System.Linq;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.OData;
using Microsoft.WindowsAzure.Mobile.Service;
using FringProjectMobileService.DataObjects;
using FringProjectMobileService.Models;
namespace FringProjectMobileService.Controllers
{
public class StorageItemController : TableController<StorageItem>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
FringProjectMobileServiceContext context = new FringProjectMobileServiceContext();
DomainManager = new EntityDomainManager<StorageItem>(context, Request, Services);
}
// GET tables/StorageItem
public IQueryable<StorageItem> GetAllStorageItem()
{
return Query();
}
// GET tables/StorageItem/xxxxxxxxxx
public SingleResult<StorageItem> GetStorageItem(string id)
{
return Lookup(id);
}
// PATCH tables/StorageItem/xxxxxxxx
public Task<StorageItem> PatchStorageItem(string id, Delta<StorageItem> patch)
{
return UpdateAsync(id, patch);
}
// POST tables/StorageItem
public async Task<IHttpActionResult> PostStorageItem(StorageItem item)
{
StorageItem current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
// DELETE tables/StorageItem/xxxxxxxxxx
public Task DeleteStorageItem(string id)
{
return DeleteAsync(id);
}
}
}
Below the other controller code trying to access the method:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Microsoft.WindowsAzure.Mobile.Service;
namespace FringProjectMobileService.Controllers
{
public class ArduinoController : ApiController
{
public ApiServices Services { get; set; }
// GET api/Arduino
public string Get()
{
Services.Log.Info("Hello from custom controller!");
return "Hello";
}
public async void PostProcessTag(String id)
{
Microsoft.WindowsAzure.MobileServices.MobileServiceClient client = new Microsoft.WindowsAzure.MobileServices.MobileServiceClient("http://some-service.azure-mobile.net", "XXXXXXXXXXXXXXX");
Microsoft.WindowsAzure.MobileServices.IMobileServiceTable<DataObjects.StorageItem> storage_item_table = client.GetTable<DataObjects.StorageItem>();
await storage_item_table.ToEnumerableAsync();
}
}
}
I also tried a different implementation for the method :
public void PostProcessTag(String id)
{
StorageItemController table_controller = new StorageItemController();
IQueryable<DataObjects.StorageItem> item = table_controller.GetAllStorageItem();
}
The service context:
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using Microsoft.WindowsAzure.Mobile.Service;
using Microsoft.WindowsAzure.Mobile.Service.Tables;
namespace FringProjectMobileService.Models
{
public class FringProjectMobileServiceContext : DbContext
{
// You can add custom code to this file. Changes will not be overwritten.
//
// If you want Entity Framework to alter your database
// automatically whenever you change your model schema, please use data migrations.
// For more information refer to the documentation:
// http://msdn.microsoft.com/en-us/data/jj591621.aspx
//
// To enable Entity Framework migrations in the cloud, please ensure that the
// service name, set by the 'MS_MobileServiceName' AppSettings in the local
// Web.config, is the same as the service name when hosted in Azure.
private const string connectionStringName = "Name=MS_TableConnectionString";
public FringProjectMobileServiceContext() : base(connectionStringName)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
string schema = ServiceSettingsDictionary.GetSchemaName();
if (!string.IsNullOrEmpty(schema))
{
modelBuilder.HasDefaultSchema(schema);
}
modelBuilder.Conventions.Add(
new AttributeToColumnAnnotationConvention<TableColumnAttribute, string>(
"ServiceTableColumn", (property, attributes) => attributes.Single().ColumnType.ToString()));
}
public System.Data.Entity.DbSet<FringProjectMobileService.DataObjects.StorageItem> StorageItems { get; set; }
}
}

Categories