How can I get Object from Table in Entity Framework - asp.net

I have a database table and corresponding class in entity framework. Please tell me how to get data from database and directly set into class object. Here is my code.
It's giving an error like cannot implicitly convert type Jobportel.Member to Jobportel.DTO.MemberDTO.
public MemberDTO getMember(String email) {
MemberDTO member= null;
using (var db = new jobportaldatabaseEntities()) {
member= db.Members.SingleOrDefault(e => e.email == email);
}
return member;
}

Related

Put method in web api (EF)

I am using a web api put method. I need to update two columns in the database. But I'm having an issue on updating both column.
I've got an error stated below
System.NullReferenceException: 'Object reference not set to an
instance of an object.'
emp was null.
This is my current code;
public class EmployeeController : ApiController
{
public HttpResponseMessage Put(int id, [FromBody] Employee emp)
{
try
{
using (EmpDBContext dbContext = new EmpDBContext())
{
var entity = dbContext.Employees.FirstOrDefault(e => e.Index == id);
if (entity != null)
{
entity.Name = emp.Name;
entity.EmpNum = emp.EmpNum;
dbContext.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK, entity);
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound,
"Employee with Id " + id.ToString() + " not found to update");
}
}
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
}
Need some advice regarding this issue.
When you try to use any value in c# which is null then you will get 'Object reference error'. You need to see the API calling method to check why emp is coming null.
Below are the possibility -
Passing parameter name from calling method should exactly same as the name in parameter of the API, in your case it should be emp.
Check your Employee Model if it matching with your calling method properties.
You can check this info from Network tab of your browser.

Web service send id to another source and return information

So I am kind of new to Web services, and I am trying to wrap my head around how it works.
Basically, I need to receive an ID from one side, pass it to another source which returns the employee information.
Now, this is what I did so far:
[WebMethod(Description = "Returns employee object for id")]
public Employee GetEmployeeById(int Id)
{
// how to ?
return new Employee( // data from outer source);
}
I see the wsdl, where you can send the id to the function.
How does the other source get the information from my service?
The another source means that anywhere you want to connect to. Maybe it's a database, other web service, or only a text file....
For example, you have a db that saves employee data. You can use Entity Framework to get employee data from db.
Like this:
[WebMethod(Description = "Returns employee object for id")]
public Employee GetEmployeeById(int Id)
{
using(var context = new MyDbContext())
{
var emp = context.Employees.Where(x => x.Id == Id).FirstOrDefault();
return emp;
}
}

ASP.NET Entity Framework return JSON object of all rows inside table

I am trying to return JSON object from PostgreSQL db and currently saving to database works fine, but trying to return result returns nothing this is currently what I have for returning list from db. Keep in mind connection string is fine functionality for creating object to db works fine.
public async Task<IEnumerable<TutorialMake>> ReadTutorialMake()
{
try
{
using (var db = new TutorialContext())
{
response = HttpStatusCode.OK;
return db.TutorialMakes.ToList();
}
} catch
{
response = HttpStatusCode.BadRequest;
return null;
}
}
I've tried with returning only db.TutorialMakes without enumerable still nothings, removing try and catch returns no errors, iqueryable returns nothing and there is data inside table
Code is fine, it was just the way I configured my API I didn't return the list in API.
Because you forget to convert List result to JsonObject
Example :
public async Task<JsonResult> ReadTutorialMake()
{
try
{
using (var db = new TutorialContext())
{
response = HttpStatusCode.OK;
return Json(db.TutorialMakes.ToList()); //Convert result to JsonResult
}
} catch
{
response = HttpStatusCode.BadRequest;
return null;
}
}

Create a entity framework LINQ group join query to return a subset of properties from DTO and a list of another DTO, ASP.net core

So, I tried searching and couldn't really find an answer that was explicit enough and guided me to my solution so I thought I would add my problem and ultimately my solution for others to benefit.
Pardon my newness to SO (consider this my start of getting my reputation up), let me know if I do anything incorrect or forget anything.
I am trying to:
Create a controller that queries a database for all the users and their roles.
Return the list of unique users id's and email address with a List of roles.
The email address and roles are in separate tables and the pkey/fkey is the user id
The roles are returned as a list containing my AllUserInRolesDto
Every example I looked at on SO or other sites only provided examples of returning anonymous data objects back. I don't have a lot of LINQ query syntax so had me stuck for an hour or so.
Here is my DTO
namespace Lib.Dtos
{
public class AllUserInRolesDto
{
public string FullName { get; set; }
public string Email { get; set; }
public List<RoleDto> Roles { get; set; }
}
public class RoleDto
{
public string RoleName { get; set; }
}
}
I have a business layer that defines the LINQ query
public List<AllUserInRolesDto> UserAllRolesGet()
{
List<AllUserInRolesDto> getAllUsersRoles = (from u in _context.Users
join r in _context.UserInRoles on u.UserId equals r.UserId
into ur
select new Lib.Dtos.AllUserInRolesDto()
{
FullName = u.Fullname,
Email = u.Email,
Roles = ur //this was the problem line and what the docs were describing
}).ToList();
return getAllUsersRoles;
}
...and my controller
[HttpGet("GetAllUserRolesList")]
public IActionResult GetAllUserRolesList()
{
List<Lib.Dtos.AllUserInRolesDto> allUsers = _userBL.UserAllRolesGet();
return new JsonResult(allUsers);
}
my solution
After taking a step back for a second I realized I actually wasn't returning the right object back to my roles property...and so need to iterate over my roles and create a list from them. Here is what worked.
public List<AllUserInRolesDto> UserAllRolesGet()
{
List<AllUserInRolesDto> getAllUsersRoles = (from u in _Context.Users
join r in _context.UserInRoles on u.UserId equals r.UserId
into ur
select new Lib.Dtos.AllUserInRolesDto()
{
FullName = u.Fullname,
Email = u.Email,
Roles = .Select(x => new Lib.Dtos.RoleDto() { RoleName = x.RoleName }).ToList() //Changed to this
}).ToList();
return getAllUsersRoles;
}
Anyway, probably a pretty dumb mistake, but had me stuck for a bit. Maybe this helps someone in my same position or if someone has a comment of how I could have improved this or used a different approach I am open to hearing suggestions.
I assume you're using Entity Framework, and that you have your DB model defined with relationships. This means you don't need to use explicit JOINs in your queries: you can use navigation properties instead.
Your "business layer" (note that you don't necessarily always need a business layer) should only work with Entity types and should not use DTOs (as DTOs belong to your web-service, in the same way that View-Models belong to a web-application).
If your "business layer" just consists of predefined queries, I recommend defining them as static extension methods for your DbContext and returning IQueryable<T> instead of as materialized List<T> as this enables your consumers to perform further operations on them (such as additional filtering or sorting and paging).
I recommend doing it like this instead:
// Queries methods (i.e. "business layer" queries)
public static class QueriesExtensions
{
public static IQueryable<User> GetAllUsersAndTheirRoles( this MyDbContext db )
{
// I assume `UserInRoles` is a linking table for a many-to-many relationship:
return db
.UserInRoles
.Include( uir => uir.User )
.Include( uir => uir.Role )
.Select( uir => uir.User );
}
}
// Web-service controller:
[HttpGet("GetAllUserRolesList")]
[Produces(typeof(List<AllUserInRolesDto>)]
public async Task<IActionResult> GetAllUserRolesList()
{
List<User> usersList = await this.db
.GetAllUsersAndTheirRoles()
.ToListAsync();
List<Lib.Dtos.AllUserInRolesDto> usersListDto = usersList
.Select( u => ToDto( u ) )
.ToList();
return new JsonResult( usersListDto );
}
// Entity-to-DTO mapping functions (if you have a lot of DTOs and entities, consider using AutoMapper to reduce the tedium)
private static AllUserInRolesDto ToDto( User user )
{
return new AllUserInRolesDto()
{
FullName = user.FullName,
Email = user.Email,
Roles = user.Roles.Select( r => ToDto( r ) ).ToList()
};
}
private static RoleDto ToDto( Role role )
{
return new RoleDto()
{
RoleName = role.RoleName
};
}

Using a custom method in LINQ to Entities

I have a LINQ expression:
var users = db.Relationships.Where(i => i.RelationshipId== relId)
.Select(s => s.User).Distinct().Select(s => new UserViewModel() {
Username = s.Username,
LastActiveDateTime = s.LastActive, // DateTime, I want it to be a string filtered through my custom GetFriendlyDate method
}).ToList();
// convert all DateTimes - yuck!
foreach (var userViewModel in users) {
userViewModel.LastActive = DateFriendly.GetFriendlyDate(userViewModel.LastActiveDateTime);
}
This solution is working, but it feels wrong to
have to iterate over all users after getting them from the db, just to reformat a property on every single one
have a DateTime property on my ViewModel just so that it can later be converted to a string and never touched again
Is there any way I can use the GetFriendlyDate method directly within the query?
Possible solutions, worth to mention:
Have a getter property of your ViewModel, which would return transformed string, something like:
public string LastActive
{
get
{
return DateFriendly.GetFriendlyDate(LastActiveDateTime);
}
}
Though it not solves your problem with existing LastActiveDateTime column, transformation will be applied only at moment of usage (in your view, most likely - anyways if you will try use it somewhere latter in query, it will not work for reason you already know), so no need to iterate manually.
Create View, which will transform data on server side; so your data will already be returned in format you need, if you're using DBFirst, probably, it's easiest and fastest solution;
Finally, you can use ToList() twice, once before selecting new ViewModel() (or call AsEnumerable(), or find other way to materialize query). It will fetch data from database and will allow you perform any C#-side functions you want directly in query after ToList(). But, as mentioned before - it's about getting all data, which matched criteria up to ToList() - in most cases it's not appropriate solution.
And here is some additional readings:
How can I call local method in Linq to Entities query?
I tested it in LINQpad and it works.
It still kinda iterates over users (with LINQ) but you don't have to add DateTime property to your viewmodel class. Also you could convert collection of Users to collection of UserViewModel objects with Automapper. It would still iterate over users of course but you wouldn't see it.
Had to create some setup code of course because I don't have your database.
void Main()
{
var db = new List<User> {
new User { LastActive = DateTime.Now, Username = "Adam", Lastname = "Nowak" },
new User { LastActive = DateTime.Now.AddYears(1), Username = "Eve", Lastname = "Kowalska"}
};
// select only properties that you need from database
var users = db
.Select(user => new { Username = user.Username, LastActive = user.LastActive})
.Distinct()
.ToList();
var usersVM = from u in users
select new UserViewModel { Username = u.Username, LastActiveDateTime = DateFriendly.GetFriendlyDate(u.LastActive)};
usersVM.Dump();
}
class User
{
public DateTime LastActive;
public string Username;
public string Lastname;
};
class UserViewModel
{
public string Username;
public string LastActiveDateTime;
}
static class DateFriendly
{
public static string GetFriendlyDate(DateTime date)
{
return "friendly date " + date.Year;
}
}
And this outputs
Username LastActiveDateTime
Adam friendly date 2013
Eve friendly date 2014
There is no direct Concert.ToDate method available for LINQ. But you can try using the DateAdd method from the SqlFunctions class:
var users = db.Relationships.Where(i => i.RelationshipId== relId)
.Select(s => new
{
s.User.Username,
LastActive=SqlFunctions.DateAdd("d",0, s.LastActive)
})
.ToList().Select(s => new UserViewModel()
{
Username = s.Username,
LastActiveDateTime = s.LastActive
});
Wouldn't the following work?
var users = db.Relationships.Where(i => i.RelationshipId== relId)
.Select(s => s.User).Distinct().Select(s => new UserViewModel() {
Username = s.Username,
LastActiveDateTime = DateFriendly.GetFriendlyDate(s.LastActive)
}).ToList();

Resources