Getting Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[ProjectName.DTOs.ProjectDTO] instead of actual Data - linq

I am working on my .NET MVC Core project. I am trying to get the project name by joining two tables using LINQ in my Controller.
My Controller code:
public IActionResult Projects()
{
var projectName = from p in _context.Tbl_Projects
join d in _context.Tbl_MyOfficeDocumets on p.Id equals d.Project_ID
select new ProjectDTO { ProjectName = p.ProjectName };
ProjectDTO proj = new ProjectDTO { ProjectName = projectName; }
return View(proj);
}
And Razor view page:
<table>
<tr>
<td>Your Projects</td>
<td>Description</td>
<td>Created On</td>
</tr>
#foreach(var item in Model.listOfProjects)
<tr>
<td>#Model.ProjectName</td> <-- Here I am getting that unusual response
<td>#item.Description</td>
<td>#item.CreatedOn</td>
</tr>
</table>
The #Model.ProjectName shows:
Getting Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[ProjectName.DTOs.ProjectDTO]
Am I missing something?

You have created query and assigned it to DTO, which is wrong.
public IActionResult Projects()
{
var query = from p in _context.Tbl_Projects
join d in _context.Tbl_MyOfficeDocumets on p.Id equals d.Project_ID
select new ProjectDTO { ProjectName = p.ProjectName };
return View(query);
}

Related

How can I get data from from table2 by sending corresponding ID from table1 using thymleaf

getFunction() in database class:
public Review getReviews(Long id) {
MapSqlParameterSource namedParameters = new MapSqlParameterSource();
String query = "SELECT * FROM reviews WHERE id = :id";
namedParameters.addValue("id", id);
BeanPropertyRowMapper<Review> reviewMapper = new BeanPropertyRowMapper<Review>(Review.class);
List<Review> reviews = jdbc.query(query, namedParameters, reviewMapper);
if (reviews.isEmpty()) {
return null;
} else {
return reviews.get(0);
}
}
Controller class:
#GetMapping("/viewReview")
public String viewReviews(Model model,Long id) {
List<Review> review = da.getReviews(id);
model.addAttribute("reviewList", review);
return "view-book";
}
HTML:
<tr th:each="book : ${bookList}">
<td th:text="${book.title}"></td>
<td th:text="${book.author}"></td>
<td> View</td>
</tr>
I have two tables 'books' and 'reviews'. When I click the first book it should display the corresponding review of the book on the next page. But instead shows 404 error. Im guessing Im missing something in my database class but not sure what.
I'm not very familiar with Thymeleaf, but looking at your Controller (and the error message), the problem could be with your Controller than Database class.
Your viewReviews method is mapped for /viewReview, but you are trying to navigate to /viewReview/BOOK_ID, which is why you are getting the 404 error message.
Try updating your Controller as:
#GetMapping("/viewReview/{id}")
public String viewReviews(Model model, #PathVariable("id") Long id) {
List<Review> review = da.getReviews(id);
model.addAttribute("reviewList", review);
return "view-book";
}

MVC Using relationships Database first

First off I have a list of movies setup from a database working fine on localhost/movies
However I wanted to go a step further so I created an Actors page, I now list all the Actors to ( On their own just their names )
What I want to do is you have for example -
Leonardo DiCaprio (id = 1)
I would like to check the page to see if the id matches him etc ( This is already done as you will see in code below )
Next I would like All his movies he has been in to be shown in another row on the table. As you can see VIA This screenshot
http://gyazo.com/ae193d80e7a39969116f76ab6568f38e.png
Instead of just the movies he has starred in they all show up, as you can see below I made a relationship between tables Actor & Movie & ActorsMovies, just linking the Ids
I have 3 tables setup like the following:
Movies -
Id (PK),
Name
Actor:
Id(PK),
Name
ActorsInMovies:
MovieId(PK),
ActorId(PK)
Here is my controller:
public ActionResult Movies( int id )
{
var model = MoviesViewModel(); //Create our model
model.PageTitle = = actor.Name + "'s' Movies"; // set page title to actors name
model.Actorname = actor.Name; // I do this to ensure the name always matches the id
var items = db.Movies.OrderBy(i => i.Name).AsQueryable(); //Link items to Movies DB and make it queryable ( as I want to use pagedLists later when its working )
if (!String.IsNullOrEmpty(actor.Name)) //if name is not null
{
items = items.Where( a => a.Id == id );//I already know this is wrong but I dont know what the correct process is I think the theory part behind it I understand, here I need to check the relationships to ensure that the actor matches with the movies I just am unsure how to do it.
}
model.MovieList = items.ToList();
return View(model);
}
and my views is just a normal table with foreach loop in ( im gonna remove the Html so it doesnt get to messy:
#foreach (var item in Model.MovieList)
{
<tr>
<td>#Html.DisplayFor(modelItem => Model.Actorname)</td>
<td>
<!-- MS:This part populates the table row-->
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Id }, new { #class = "btn btn-default" })
#Html.ActionLink("Details", "Details", new { id = item.Id }, new { #class = "btn btn-default" })
#Html.ActionLink("Delete", "Delete", new { id = item.Id }, new { #class = "btn btn-danger" })
</td>
</tr>
}
The easiest way to map many-to-many relationships in MVC and to also limit the number of database queries, is like below. This also does pagination, since you mentioned the desire.
MovieActor schema: (many-to-many map of Movie and Actor)
ID (PK)
ActorID (FK to Actor.ID)
MovieID (FK to Movie.ID)
CharacterName
Controller:
const int Rows = 50; // put this wherever appropriate, or customize and save in Session
/// <summary>
/// This shows all the Movies the given Actor was in.
/// </summary>
/// <param name="id">Actor ID</param>
/// <param name="page">Page of Movies to display, starting at 1</param>
public ActionResult Movies(int id, int page = 1)
{
// get the actor
Actor actor = MyDataContext.GetActorByID(id); // one database call
// get the actor's movies
List<Movie> movies = MyDataContext
.GetMoviesByActorID(actor.id) // no database call
.Skip((page - 1) * Rows)
.Take(Rows); // one database call
// build the view model
// NOTE: could move this into a constructor MoviesViewModel(actor, movies)
var viewModel = MoviesViewModel
{
PageTitle = actor.Name + "'s Movies",
ActorName = actor.Name,
Movies = movies
};
// show the view
return View(model);
}
Model:
public partial class MyDataContext
{
public Actor GetActorByID(int id)
{
return Actors.FirstOrDefault(x => x.ID == id)
}
public IQueryable<List<Movie>> GetMoviesByActorID(int actorID)
{
return Movies.Where(x => x.MovieActor.ActorID == actorID);
}
}
And the view is like any normal IEnumerable or List.

asp.net mvc linq I want to fetch two columns from two join table

I have two tables join with PrId column, I have a view which show two columns from both tables, first column from first table and second column from second table. my actionresult is :
public ActionResult extrapoints()
{
ViewBag.dList = (from m in _session.customer
join p in _session.Products on m.PrId equals p.PrId
where m.UserId== 'john'
select new { FName = m.FName, price=p.price});
return View();
}
and in view i want to show both FName and price, I have following view :
#foreach (var item in ViewBag.dList)
{
<tr>
<td>#item.FName </td>
<td> #item.price</td>
</tr>
}
but is show error object' does not contain a definition for FName but when i use without Fname,price like
#foreach (var item in ViewBag.dList)
{
<tr>
<td>#item</td>
<td> #item</td>
</tr>
}
is shows :
{ FName = Shailendra, price= 1000 }
how to solve, please help
You Can Convert the Anonymous class to typed class, first add this class
class Test
{
public string FName { get; set; }
public decimal price { get; set; }
}
and make you linq statment as
ViewBag.dList = (from m in _session.customer
join p in _session.Products on m.PrId equals p.PrId
where m.UserId== 'john'
select new Test{ FName = m.FName, price=p.price});
and finally Cast the viewpage to type "Test"
#foreach (var item in (List<Test>)ViewBag.dList)
{
<tr>
<td>#item.Fname</td>
<td> #item.price</td>
</tr>
}

Incorporating custom view model data from multiple tables into a view

I can't understand why I can't find anything that clearly explains how to do this with MVC. Seems like a pretty routine issue:
I have three tables:
PackageName: PackageNameID,PackageName
Food: FoodID,Food
PackageContent: PackageContentID, PackageNameID, FoodID, Qty
The application is supposed to describe packages of food. For example, a package named "A" might contain 4 onions and 3 peppers. Another package, "B", might contain 2 rolls and 2 onions.
Currently I have a custom view model ("PackageNameModel") that collects the data:
public ViewResult Index() {
var viewModel =
from pn in db.PackageNames
from pc in db.PackageContents
.Where(p => p.PackageNameID == pn.PackageNameID).DefaultIfEmpty()
from f in db.Foods
.Where(f => f.FoodID == pc.FoodID).DefaultIfEmpty()
select new PackageFoodModel { PackageName = pn, PackageContent = pc, Food = f };
return View( viewModel );
}
This returns the data correctly, but what do I do with it so that the view is actually one that is useful for the application?
Using this in my view:
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.PackageName.PackageName1 ) ,
#Html.DisplayFor(modelItem => item.Food.Food1)=#Html.DisplayFor(modelItem => item.PackageContent.Qty)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.PackageName.PackageNameID }) |
#Html.ActionLink("Details", "Details", new { id = item.PackageName.PackageNameID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.PackageName.PackageNameID })
</td>
</tr>
}
I am able to display the following:
- A , Onions=4 Edit | Details | Delete
- A , Peppers=3 Edit | Details | Delete
- B , Rolls=2 Edit | Details | Delete
- B , Onions=2 Edit | Details | Delete
This is not very useful. What I'm trying to do is display something like this:
- A (Onions=4,Peppers=3) Edit | Details | Delete
- B (Rolls=2,Onions=2) Edit | Details | Delete
Eventually, the next page down after navigating to the "Edit" action would provide an editable name for the package as well as a table of all available foods and an adjacent quantity box so that the foods/quantities within each package may be updated.
Can anyone explain how this is done within the MVC framework?
All the tutorials I have seen on the web/in books deal with data that is much simpler. Can anyone point me to some sample code / tutorials that deal with something like this?
Thanks in advance!
You need to aggregrate your results.
Create a view model like this
public class PackageViewModel
{
public int ID { set;get;}
public string Name { set;get;}
public List<FoodItem> FoodItems { set;get;}
public PackageViewModel()
{
FoodItems=new List<FoodItem>();
}
}
public class FoodItem
{
public string FoodName { set;get;}
public int Quantity { set;get;}
}
and in your Get action, You need to do the aggregate the data from your data which is ccoming from your data access layer and fill to the ViewModel List
public ActionResult IndeX()
{
List<PackageViewModel> listVM=new List<PackageViewModel>();
//Get your data and do aggregation and fill in listVM
return View(listVm)l
}
and in our view,
#model List<PackageViewModel>
#foreach(var item in Model)
{
<tr>
<td>#item.Name</td>
<td>
foreach(var food in item.FoodItems)
{
#food.FoodName - #food.Quantity
}
</td>
<td>
#Html.ActionLink("Edit","Edit",new {#id=item.ID})
</td>
</tr>
}

ASP.NET MVC How to pass a joined data into view?

I have the following code in my controller:
public ViewResult Index()
{
var q = from ci in db.City
join co in db.Country on ci.CityID equals co.CityID
select ci;
return View(q);
}
the database are as follow:
Table City: CityID, CityName
Table Country: CountryID, CountryName
in the index view how do I display both the CityName and CountryName:
#foreach (var item in Model) {
#Html.DisplayFor(modelItem => item.CityName)
and I can't get it to display CountryName :(
Thanks!
It doesn't work because you're only selecting the city in your query. You need to select both. Using an anonymous object is one way:
select new { City = ci, Country = co }
You should then be able to access item.City.Cityname, item.Country.CountryName etc.

Resources