I have a database CarsDB with a table Car with some columns (like mileage or model)
And I want to get info from that table in a controller I write:
public ActionResult Index()
{
return View(db.CarsDB.ToList()):
}
But I'm getting an error (something like method CarsDB not found). The error is long and I don't know hot to translate it to English :( Also, when I write db, the only suggetions I'm getting are "Equals", "GetHashCode" and some others, not with CarsDB
Try
db.Cars.ToList()
You need to query the table (cars) - right now you're saying "select everything from the CarsDB database", rather than "select everything from the Cars table in the CarsDB database".
To clarify - your db variable should be an instance of a data context or entities.
Full code should look something like this:
public ActionResult Index()
{
CarsDB db = new CarsDB();
return View(db.Cars.ToList()):
}
If you're using Entity Framework you could do something like:
public ActionResult Index()
{
using (CarsDB dataContext = new CarsDB())
{
return View(dataContext.Cars.ToList()):
}
}
This will also assure automatic disposal of your data context.
Related
I am trying to make a function that will help me get needed data quickly.
With all the trials I have been able to get to the following
Tables:
Users (id,name)
Projects (id,name)
User-Project (id, user_id, project_id, manager) where manager is a boolean , there can only be one manager for each project (but employees can still see the project reason why we have a pivot table, manager = 0 for other normal users that can access that project)
In the Project Model I have:
public function Manager(){
return $this->belongsToMany('App\User')->wherePivot('manager', true);
}
In the View I have:
<p><strong>Project Manager:</strong> {{$project->manager}}</p>
On the actual page I get:
Project Manager: [{"id":4,"name":"Daniel Doe","email":"danieldoe#hotmail.com","phone":"70846556","email_verified_at":null,"created_at":"2020-12-20 21:05:50","updated_at":"2020-12-20 21:05:50","pivot":{"project_id":1,"user_id":4,"manager":1}}]
When I change the view to:
<p><strong>Project Manager:</strong> {{$project->manager[0]->name}}</p>
I get:
Project Manager: Daniel Doe
This is what I actually want but I would like to do it from the model if possible. So I tried:
public function Manager(){
return $this->belongsToMany('App\User')->wherePivot('manager', true)->first()->name;
}
But I get the following error:
must return a relationship instance
Can this be done from the model's function?
You can keep your defined relationship, but to access ->first()->name, you'll need to use an "Accessor":
public function manager() {
return $this->belongsToMany('App\User')->wherePivot('manager', true);
}
public function getManagerNameAttribute() {
return $this->manager->first() ? $this->manager->first()->name : 'No Manager';
}
Then, in your code, you simple access:
{{ $project->manager_name }}
If your manager() function returns a Collection of at least 1 record, it will return the name, otherwise it will display 'No Manager' as a fallback.
If you don't want to change the structure of this you can use an accessor to get this information, roughly something like this:
class Project ...
{
public function users()
{
return $this->belongsToMany(...)->withPivot(...);
}
public function getManagerAttribute()
{
return $this->users()->wherePivot('manager', 1)->first()?->name;
}
}
You can do this in different ways, you could use the loaded users relation and use a the Collection methods to filter the manager. You could create another relationship called managers that uses the wherePivot off of users(), etc ...
The only thing to worry about with this setup is that every call to $model->manager would be causing that query, so it may be a good idea to create another relationship manager so that you can load that once and keep using it without the need to keep querying the database:
public function managers()
{
return $this->users()->wherePivot(...);
}
public function getManagerAttribute()
{
return $this->managers->first()?->name;
}
Though, as mentioned already it is probably better to have something like a manager_id on the Project itself.
public APIController()
{
db = new ApplicationDbContext();
}
ApplicationDbContext db;
[HttpGet]
public List<Category> GetCategories()s
{
return db.Categories.ToList();
}
I am trying to get categories from the Web API. I am using AJAX, but it gives a 500 exception.
Since connection string is right and all setup correctly, There are 2 possible issues in the code I see:
1- Your Api Controller is named APIController which is a reserved word in .NET Api
2- Your get service is trying to return a complete Object from categories which might be related to parent objects and the parent objects are related to other related objects which results in returning the whole database.
I suggest using select new in lambda like this:
[HttpGet]
public List<Category> GetCategories()s
{
return db.Categories.Select(a => new { a.Name, a.ID, a.Description }).ToList();
}
This way you avoid querying the whole database.
I have database CarsDB, with Table Car in it. I whant to see the car table, but getting only System.Data.Objects.ObjectSet`1 instead of database table
public CarsBDEntities db = new CarsBDEntities();
public ActionResult Index()
{
ViewBag.Carlist = db.Cars.ToString();
return View();
}
I have make a table, then created a model from it. Using entity frameworkd and ado.net.
You don't want to use ToString; if you just return db.Cars instead, that will give you an IEnumerable that you can work with.
var cars = db.Cars;
return View(cars);
You can use this to make a Webgrid that will display your data. Razor view:
#model IEnumerable<Namespace.Models.Cars>
#{
var grid = new WebGrid(Model);
}
#grid.GetHtml()
You're trying to convert an ObjectSet to a string, which is why your getting "System.Data.Objects.ObjectSet". You'll need to pull the data out of the table to view it. For instance, something like:
string firstCarMake = db.Cars.FirstOrDefault().Make.ToString();
Updating an object with MVC3
I have a model that I can modify, please see the sample below:
[HttpPost]
public ActionResult Edit(Company c)
{
if (ModelState.IsValid)
{
db.Entry(c).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(c);
}
The model has other fields that are not showing in the view and cannot be modified by the user, but when I click the submit button the fields that were not showing in the view got set to null.
Can I somehow let EF know not to modify certain fields? Thanks.
Generally it is better not to bind to the entity object directly, rather create an edit model and bind to that.
After all.. whats to stop someone posting back values you don't want changed with this approach?
The main problem here is the fact that mvc model binding changes the properties in the model before its in a context therefore the entity framework doesn't know which values have changed (and hence which should be updated)
You've mitigated that slightly with db.Entry(c).State = EntityState.Modified; but that tells the entity framework that the whole record has been updated.
I would normally do the following:
Bind to a model specifically for this controller first
Create an instance of the entity class you want to update, set the Id accordingly and attach it to the context
Update the properties on the entity to be the same as the model you binded to (object is attached and therefore entity framework is tracking which columns are being changed now)
SaveChanges
Step 3 is a bit tedious therefore consider using a tool like automapper to make things easier
Edit:
[HttpPost]
public ActionResult Edit(Company c)
{
if (ModelState.IsValid)
{
Company dbCompayObjct = new Company { companyId = c.companyId };
db.Company.Attach(dbCompayObjct);
dbCompanyObjct.CompanyName = c.CompanyName;
dbCompanyObjct.City = c.City;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(c);
}
You are apparently overwriting your existing record with an incomplete record. When you use the method above, it will completely replace the existing one.
You either need to fill in all the fields you don't want to replace with the existing values, or you need to get the existing record and modify the fields you want to modify, then save it.
Reflection is not always evil, sometimes it's your friend:
public ActionResult Edit(Company c)
{
if (ModelState.IsValid)
{
Company UpdateC = db.Company.find(c.CompanyID);
foreach (var property in typeof(Company).GetProperties())
{
var propval = property.GetValue(c);
if (propval != null)
{
property.SetValue(UpdateC, propval);
}
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(c);
}
Hi there I am hoping someone can point me in the right direction.
I want to create an mvc applicaton I have worked my way through the music store example and still am not 100% sure the correct way to do things.
Lets say I want to create an application that stores cooking receipes.
I have a 3 tables
RecipeTable
RecipeID
RecipeName
RecipeIngredients
RecipeIngredientID
RecipeID
IngredientID
Measurement
IngredientTable
IngredientID
IngredientName
All have PK & FK mappings very basic, I create a new mvc application and use the entity framework to create a new entity e.g. RecipeDB
My next step is I create a new model for each of the tables and give the properties my desired displaynames and specify required fields extra.
Do I then create a viewmodel e.g. RecipesViewModel that looks something like
public class RecipesViewModel
{
public int RecipeID { get; set; }
public string RecipeName { get; set; }
public List<RecipeIngredients> { get; set; }
}
I now create the controller (Ithink) but I am not really sure how to bind that to database entity.
I know you can call the database by doing something like RecipeEntities db = new recipeEntites(); however binding the results to the vm I am little confussed on how to do that.
Am I heading in the right direction so far?
You could use AutoMapper. It's a great tool allowing you to convert from one type to another and in your case from the model to the view model.
public ActionResult Foo()
{
RecipeDB model = _repository.GetRecipies();
RecipesViewModel viewModel = Mapper.Map<RecipeDB, RecipesViewModel>(model);
return View(viewModel);
}
or you could even define a custom action attribute (like the one I used in my sample MVC project) allowing you to simply write:
[AutoMap(typeof(RecipeDB), typeof(RecipesViewModel))]
public ActionResult Foo()
{
RecipeDB model = _repository.GetRecipies();
return View(model);
}