How to display details from database to the single user in mvc - asp.net-mvc

I am trying to get the details from database to display in the View. Here I need to display the records for particular user who logged currently. But unfortunately all the data which ever in DB table coming into the view. But I dont want to display all the data.
In DB I have two tables for tblEmployee and TaskDetails.
This is my Model:
public class TaskDetails
{
public string ProjectID { get; set; }
public string ProjectName { get; set; }
public DateTime StartDate { get; set; }
public DateTime EstimatedDate { get; set; }
public string TaskDescription { get; set; }
}
This is My controller,
To fetch the data here I am using ADO.Net,
public ActionResult TaskDetails(string td)
{
string connectionstring = "data source = NLTI37; initial catalog = Data; integrated security = True; MultipleActiveResultSets = True; App = EntityFramework";
string sql = "select * from TaskDetail";
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand(sql, conn);
var Details = new List<TaskDetails>();
{
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
var ProjectDetail = new TaskDetails();
ProjectDetail.ProjectID = rdr["ProjectID"].ToString();
ProjectDetail.ProjectName = rdr["ProjectName"].ToString();
ProjectDetail.StartDate = DateTime.Parse(rdr["StartDate"].ToString());
ProjectDetail.EstimatedDate = DateTime.Parse(rdr["EstimatedDate"].ToString());
ProjectDetail.TaskDescription = rdr["TaskDescription"].ToString();
Details.Add(ProjectDetail);
}
}
return View(Details);
}
Here I am using ADO.Net to fetching the details. And these details I need to display on the View for user who currently logged in.
This is my View:
<tbody>
#foreach (var ProjectDetail in Model)
{
<tr>
<td>#ProjectDetail.ProjectID</td>
<td>#ProjectDetail.ProjectName</td>
<td>#ProjectDetail.StartDate</td>
<td>#ProjectDetail.EstimatedDate</td>
<td>#ProjectDetail.TaskDescription</td>
</tr>
}
</tbody>
Here I need to display the records of the user who logged in currently. But unfortunately all the user details I am getting here. As per my understanding SQL statement is wrong. Correct Me if wrong. How to get the details for that particular user details. Can any one help on this.

I think you should have to use where clause. Try this.
I assumed that td is your ProjectID
string sql = "select * from TaskDetail where ProjectID=#ProjectID";
SqlConnection conn = new SqlConnection(connectionstring);
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#ProjectID", td);

Related

How to show data from two contexts in single view in ASP.NET Core

I'm sorry for my poor command of English.
To display a list of users for each consultant, I need to first display the first name, last name, phone number and field on a page in ASP.NET Core 5.
To do this, I need to be able to merge AspNetUsers and Students tables so that I can take information from them and save it in the view model so that I can show it on one page.
But the problem is that I can not merge these two tables. I even used the Join method in Linq, but I got an error.
Needless to say, these two tables are already relationshiped and the only problem is the simultaneous display of information from these two contexts - one IdentityDbContext and other is PlanContext.
Thank you!
View model Adminshowusers :
public class Adminshowusers
{
public string FirstName { get; set; }
public string LastName{ get; set; }
public string PhoneNumber{ get; set; }
public string Field { get; set; }
}
And my action method that did not work
public async Task<IActionResult> ConsultantIndex(string Msg,string id)
{
var data = await _userManager.GetAllUsersWithRolesAsync();
var users = (from u in data
join a in _context.Students
on data.Select(x=>x.Id) equals a.ID
select new AdminAddUsers()
{
FirstName = u.FirstName,
LastName = u.LastName,
PhoneNumber = u.PhoneNumber,
Field = a.Field
});
return View(users);
}
Method GetAllUsersWithRolesAsync() is also pre-created and displays a list of all users along with their roles:
public async Task<List<UsersViewModel>> GetAllUsersWithRolesAsync()
{
return await Users.Select(user => new UsersViewModel
{
Id = user.Id,
Email = user.Email,
UserName = user.UserName,
PhoneNumber = user.PhoneNumber,
FirstName = user.FirstName,
LastName = user.LastName,
BirthDate = user.BirthDate,
IsActive = user.IsActive,
LastVisitDateTime = user.LastVisitDateTime,
Image = user.Image,
RegisterDate = user.RegisterDate,
Roles = user.Roles.Select(u => u.Role.Name),
}).ToListAsync();
}
I would change code a little, you can't join code in server with code in database. At first bring all students from db and after this join with another list.
var data = await _userManager.GetAllUsersWithRolesAsync();
var students = await _context.Students.Select(i=> new {ID=i.ID, Field=i.Field}).ToListAsync();
var users = (from u in data
join a in students on u.Id equals a.ID
select new AdminAddUsers()
{
FirstName=u.FirstName,
LastName=u.LastName,
PhoneNumber = u.PhoneNumber,
Field =a.Field
}).ToList();
return View(users);

getting all rows from db mvc asp.net

var listdata = db.UserDetails.Select(m => new SelectListItem
{
Value = m.userid.ToString(),
Text = string.Format("{0}{1}{2}{3}",m.bankname,m.userid,m.gender,m.name)
});
Here UserDetails is the table that is present in the database and this is the way i am trying to display every entry of the table.
Controller
[HttpGet]
public ActionResult getAll()
{
var listdata = db.UserDetails.Select(m => new SelectListItem
{
Value = m.userid.ToString(),
Text = string.Format("{0}{1}{2}{3}",m.bankname,m.userid,m.gender,m.name)
});
return View("getAll", listdata);
}
View
#model UserApp.Models.UserDetails
#{
ViewBag.Title = "getAll";
}
<h2>getAll</h2>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.name)
</td>
<td>
#Html.DisplayFor(modelItem => item.gender)
</td>
</tr>
}
Model
namespace UserApp.Models
{
public class UserModel : IEnumerable<UserModel>
{
public int userid {get; set;}
public string name{get; set;}
public IList<SelectListItem> bankname { get; set; }
public string gender{get; set;}
}
}
How do i get the elements and display them properly on the view?
I can't seem to get a proper solution.
Stuck on this thing for hours.
P.s: new to it, any help will be appreciated.
First, add ToList() for your listdata to make it list, currently it is still IQueryable , second your view accepts model, you are passing list of model, I guess you want that to be list not model, something like this
#model List<UserApp.Models.UserDetails>
Third, you are selecting SelectListItem but you are using UserApp.Models.UserDetails, I think you should be doing something like this
var listdata = db.UserDetails.ToList().Select(x => new UserApp.Models.UserDetails {
userid = x.userid, (repeat the same for all)
}).ToList();
because looking at your code you don't need selectListItem, you need UserApp.Models.UserDetails.
That should fix all your problems, I hope I didn't miss any.
My approach may not be the best approach but it seems to work for me.
I usually have my model for the item :
model :
namespace UserApp.Models
{
public class UserModel
{
public int userid {get; set;}
public string name{get; set;}
public IList<SelectListItem> bankname { get; set; }
public string gender{get; set;}
}
}
Then I have in my database class ( a class that calls the database and populates the queries etc: Call it CodeDB() for this example)
DB getter :
public List<UserModel> getUsers(){
{
List<UserModel> myUsers = new List<userModel>();
// however you are accessing your db do it here
string sql = "select * ...";
//access DB
//open connection
//run query command usually for me it is rdr = cmd.ExecuteReader();
while(rdr.Read()){
UserModel retrievedUser = new UserModel();
retrievedUser.userid = (int)rdr[0];
retrievedUser.name = rdr[1].ToString();
... add the other fields
myUsers.Add(retrievedUser);
}
//close db connection
return myUsers
}
In my Controller
//call my database class
CodeDB() DB = new CodeDB()
[HttpGet]
public ActionResult getAll()
{
List<UserModel> viewUsers = DB.getUsers();
ViewBag.users = viewUsers
return View();
}
in the view
#{
if(Viewbag.users != null)
{
foreach(UserApp.Models.UserModel u in ViewBag.users)
{
#Html.Raw( " userID : " + u.userid +" Gender : " + u.gender)
}
}
}
I think you could do. MVC Scaffolding of Crud with there Views Auto Generated
When you make your controller There's an option "MVC Controller with Views"
Then it will ask For your Model that you want to use for scaffolding which will be
"UserModel" Then just give your Controller a Name.
Now if you look at the Index View of your Controller it will have all the attributes you want and don't want.But of course, you can remove the unnecessary attributes
Hope this helps!

Unable to create IEnumerable on a class

I am trying to use below code in MVC and here is what I have done till now:
public class MoviesModel
{
public int Id { get; set; }
public string MovieName { get; set; }
public string Actor { get; set; }
public int Year { get; set; }
}
Controller
public MoviesModel Index()
{
MoviesModel myModel;
string connectionString =
"";
SqlConnection con = new SqlConnection(connectionString);
SqlCommand com = con.CreateCommand();
com.CommandText = "SELECT [ID] ,[MovieName] ,[Actor] ,[Year] FROM [dbo].[Movies]";
con.Open();
using (SqlDataReader reader = com.ExecuteReader())
{
while (reader.Read())
{
myModel = new MoviesModel
{
myModel.Id = Convert.ToInt32(reader[0]),
myModel.MovieName = reader[1].ToString(),
myModel.Actor = reader[2].ToString(),
myModel.Year = Convert.ToInt32(reader[3])
};
}
}
con.Close();
return myModel;
}
But I am getting below error
cannot initialize class with a collection because it does not implement System.Collection.IEnumerable
The compilation error you're getting comes with a file name and a line number, and I guarantee those things are not pointing at any of the code you've quoted.
I take that back, actually. I think this might be the source of your compilation error (telling us what line the compiler was complaining about would have helped).
myModel = new MoviesModel
{
myModel.Id = Convert.ToInt32(reader[0]),
myModel.MovieName = reader[1].ToString(),
myModel.Actor = reader[2].ToString(),
myModel.Year = Convert.ToInt32(reader[3])
};
That's not the right syntax. Inside the curly brackets is the code that will be run in order to initialize myModel - you can't refer to myModel inside the brackets, because it doesn't exist until after the code in the brackets has finished executing. Fortunately, you don't need to, because this is the syntax for setting those properties:
myModel = new MoviesModel
{
Id = Convert.ToInt32(reader[0]),
MovieName = reader[1].ToString(),
Actor = reader[2].ToString(),
Year = Convert.ToInt32(reader[3])
};
More broadly, I'll go out on a limb and guess that what you really want to do is return a collection of MoviesModel objects instead of a single MoviesModel object that happens to be the last movie in the result set. The code to do that would look something like this:
public ActionResult Index()
{
var models = new List<MoviesModel>();
string connectionString = "";
using (var con = new SqlConnection(connectionString))
using (var com = con.CreateCommand())
{
com.CommandText = "SELECT [ID] ,[MovieName] ,[Actor] ,[Year] FROM [dbo].[Movies]";
con.Open();
using (var reader = com.ExecuteReader())
{
while (reader.Read())
{
var myModel = new MoviesModel
{
Id = reader.GetInt32(0),
MovieName = reader.GetString(1),
Actor = reader.GetString(2),
Year = reader.GetInt32(3)
};
models.Add(myModel);
}
}
}
return View(models);
}
As an aside, Convert.ToInt32 is a pretty inefficient way to get something that's already an integer in the database, and in the reader. The GetInt32 method will perform better.

How does my C# MVC project setup look?

I am new to C# and MVC. I have read a few books and spent time on this site reading Q&A on various topics. I have a test project up and running to get the basics down that queries out a list of Groups and returns them to a simple View. I like the idea of the Repository pattern and have taken a stab at implementing that. A few notes... For now, I am not using EF or Linq2Sql but maybe in the future. I am not sure if I will keep my using statements in the GroupRepository or add some Dispose statements via a Try/Catch/Finally as I need a way to manage exceptions anyway.
Just wanted some advice/critique on my current setup as I continue learning.
Base.cs
namespace Test.Models
{
public class Base : IDisposable
{
protected string Connection
{
get
{
return System.Configuration.ConfigurationManager.ConnectionStrings["TestDB"].ConnectionString;
}
}
}
}
Group.cs
namespace Test.Models
{
public class Group
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public DateTime Created { get; set; }
}
}
GroupRepository.cs
namespace Test.Models
{
public class GroupRepository : Base, IGroupRepository
{
public List<Group> GetAllGroups()
{
List<Group> groups = new List<Group>();
SqlDataReader reader;
using (SqlConnection conn = new SqlConnection(Connection))
using (SqlCommand cmd = new SqlCommand("GetAllGroups", conn))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
conn.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
{
Group group = new Group();
group.ID = reader.GetInt32(0);
group.Name = reader.GetString(1);
group.IsActive = reader.GetBoolean(2);
group.Created = reader.GetDateTime(3);
groups.Add(group);
}
}
return groups;
}
}
}
IGroupRepository.cs
namespace Test.Models
{
public interface IGroupRepository
{
List<Group> GetAllGroups();
}
}
GroupController
namespace Test.Controllers
{
public class GroupController : Controller
{
private IGroupRepository _repository;
public GroupController() : this(new GroupRepository())
{
}
public GroupController(IGroupRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
return View(_repository.GetAllGroups());
}
}
}
View
#model IEnumerable<Test.Models.Group>
#{
ViewBag.Title = "Group List";
}
<table>
#foreach (var item in Model) {
<tr>
<td>
#item.ID
</td>
<td>
#item.Name
</td>
<td>
#item.IsActive
</td>
<td>
#item.Created
</td>
</tr>
}
</table>
Thanks All!
For basic projects / learning this if fine. Once you start getting into more advanced scenarios you'll find that the data you display in your views will look less like how it's stored in the database and you may want to have models which are specific to your views rather than returning the models directly from your repository into your views.
This is something you can tweak as you go however and if you're just doing basic operations then that's fine.
Another thing that tends to grow redundant quickly is having specific data access methods on your repository. Generally what I try and do is construct a query object and pass that into the repository, which executes the query and then returns the results. This tends to help me avoid redefining the IRepository contract every time I want to get a new set of data, or query by a different set of parameters.
Apart from that everything looks pretty standard and the main concept of separating data access from the controllers via the repository is solid.
Here's a (very basic) sample implementation of a query object pattern (this is really just to give you an idea, you will want to clean it up before you start using it):
public class GroupQueryParams
{
public int? GroupId {get;set;}
public string GroupName {get;set;}
}
public class GroupRepository : Base, IGroupRepository
{
public List<Group> GetGroups(GroupQueryParams query)
{
var storedProcName = "GetAllGroups";
if(query.GroupId.HasValue)
storedProcName = "GetGroupById";
if(!string.IsNullOrEmpty(query.GroupName))
storedProcName = "GetGroupByName";
//setup a parameter collection here to pass into the command
List<Group> groups = new List<Group>();
SqlDataReader reader;
using (SqlConnection conn = new SqlConnection(Connection))
using (SqlCommand cmd = new SqlCommand(storedProcName, conn))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
conn.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
{
Group group = new Group();
group.ID = reader.GetInt32(0);
group.Name = reader.GetString(1);
group.IsActive = reader.GetBoolean(2);
group.Created = reader.GetDateTime(3);
groups.Add(group);
}
}
return groups;
}
}
This way you've got a single method "GetGroups" and you can change the query params and the underlying logic as much as you want but don't have to keep redefining the interface every time you want to add a new query.

Stored Procedure Multiple-Table Output With LINQ and ASP.NET MVC

Quite often our systems call stored procedures which output multiple tables worth of results. Previously we used XML outputs to get each table and relate them correctly using XSLT. If I were using ASP.NET MVC with LINQ calling a stored procedure, how do I get each of the tables and then output the data as necessary?
this article here explains everything. This is the same article which i linked, in your previous SO question.
There's an article here about LINQ to SQL and stored procedures, especially the section 'Handling Multiple Result Shapes from SPROCs':
LINQ to SQL - Retrieving Data Using Stored Procedures.
Is that useful in your case?
Otherwise, not using LINQ to SQL, maybe use SqlDataReader's NextResult to go through the results, for example:
IList<Employee> employees = new List<Employee>();
IList<Customer> customers = new List<Customer>();
using (SqlConnection connection = new SqlConnection
(Properties.Settings.Default.NorthwindConnectionString))
using (SqlCommand command = new SqlCommand
("GetEmployeesAndCustomers", connection))
{
command.CommandType = CommandType.StoredProcedure;
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Employee e = new Employee{EmployeeID = (int)reader["EmployeeID"]};
employees.Add(e);
}
reader.NextResult();
while (reader.Read())
{
Customer c = new Customer{CustomerID = (string)reader["CustomerID"]};
customers.Add(c);
}
}
}
Edit: Example of how to handle custom data combinations that are not easily fit into domain model objects; in this case retrieving orders along with the customers for the orders:
namespace Company.Application.ViewModel
{
public class CustomerOrder
{
public string CustomerID { get; set; }
public string CustomerName { get; set; }
public int OrderID { get; set; }
public DateTime? OrderDate { get; set; }
}
}
namespace Company.Application.Repository
{
public class CustomerOrderRepository
{
public IList<CustomerOrder> GetCustomerOrders()
{
NorthwindDataContext db = new NorthwindDataContext();
var custorders = from customer in db.Customers
join order in db.Orders
on customer.CustomerID equals order.CustomerID
select new CustomerOrder
{
CustomerID = customer.CustomerID,
CustomerName = customer.CompanyName,
OrderID = order.OrderID,
OrderDate = order.OrderDate
};
return custorders.ToList();
}
}
}
Inspiration for this: In the chapter about NerdDinner, Scott Guthrie talks about creating custom 'ViewModel' objects to hold data from for example joins that are not easily fit into the domain model objects.

Resources