LINQ select new model without need of typing every parameter - c#

is it possible in LINQ to get all properties from two tables into new ViewModel without listing PersonId, Email and so on.
var person = (from o in db.Persons
join od in db.OsobeDetails on o.PersonId equals od.PersonId
where o.PersonId == id
select new PersonViewModel
{
PersonId= o.PersonId,
Email = o.Email
}).ToList();
something like:
... select new PersonViewModel();
I tried this but I don't get any results back. "id" is input parameter into method.

You could have an override of your PersonViewModel constructor that takes a Person object, and set the properties there.
For example, if you had this constructor:
class PersonViewModel
{
public PersonViewModel(Person person)
{
this.PersonId = person.PersonId;
this.Email = person.Email;
// ... other properties set here
}
}
Then you could just do:
var person = (from person in db.Persons
join od in db.OsobeDetails
on person.PersonId equals od.PersonId
where person.PersonId == id
select new PersonViewModel(person))
.ToList();

This returns both entities o and od:
var person = (from o in db.Persons
join od in db.OsobeDetails on o.PersonId equals od.PersonId
where o.PersonId == id
select new { Persons = o, OsebeDetails = od }).ToList();
access it something like:
person.Persons.PersonID
or
person.OsebeDetails.PersonID
or any other existing property.

Related

C# MVC API URL string value remove case sensitive

I have C# MVC API URL localhost/api/APIValues?Name=Nick. All working but only issue is when I typed Name=nick it won't display result. because my database table name field store Nick. Also my Database table name field has some data example Nick, ANN, tristan, Abbott,BUD. How do I remove string(Name) case sensitive MVC API values?
Example, how do I setup both way work localhost/api/APIValues?Name=Nick and localhost/api/APIValues?Name=nick.
This is my C# code.
public IEnumerable<NameDTO> Get(string Name = "")
{
var nameList = (from o in db.People.AsEnumerable()
where o.name == Name
join s in db.Employee on
o.empID equals s.empID
select new
{
s.empID,
o.Id
}).ToList();
}
My finally out put should work both name "Nick or nick"
localhost/api/APIValues?Name=Nick
localhost/api/APIValues?Name=nick
You can use Equals with StringComparison:
public IEnumerable<NameDTO> Get(string Name = "")
{
var nameList = (from o in db.People.AsEnumerable()
where o.name.Equals(Name, StringComparison.OrdinalIgnoreCase)
join s in db.Employee on
o.empID equals s.empID
select new
{
s.empID,
o.Id
}).ToList();
}
Try this, I think it may help you:
// Use if you want same records with name you provide
public List<NameDTO> Get(string Name = "")
{
var nameList = (from o in db.People.AsEnumerable()
where o.name.Trim().ToLower() == Name.Trim().ToLower()
join s in db.Employee on
o.empID equals s.empID
select new NameDTO()
{
EmpId = s.empID,
Id = o.Id
}).ToList();
}
//use this if you want similar records from database
public IEnumerable<NameDTO> Get(string Name = "")
{
var nameList = (from o in db.People.AsEnumerable()
where o.name.Trim().ToLower().Contains(Name.Trim().ToLower())
join s in db.Employee on
o.empID equals s.empID
select new NameDTO()
{
EmpId = s.empID,
Id = o.Id
}).ToList();
}
}
Made it as simple as it can get. Whenever my query's don't work in a single line it's my preference to break it down into several components. Feel happy to write a one liner though.
var nameList= db.People.AsEnumerable();
People people = new People();
foreach (var x in nameList)
{
var result = x.name.ToLower() == Name.ToLower();
if (result)
{
people = x;
}
}
var Employee = db.Employee.FirstOrDefault(e => e.EmpId == people.EmpId);
NameDTO nameDTO = new NameDTO()
{
EmpId = Employee.EmpId,
Id = People.Id
};
SQL is not case sensitive. And as long as yo're using a library that converts your code to SQL (such as EF) this shouldn't be an issue.
var nameList = (from o in db.People
where o.name == Name
join s in db.Employee on
o.empID equals s.empID
select new
{
s.empID,
o.Id
}).ToList();
The problem is that you're using AsEnumerable() which actually executes the query and then compares the objects in memory instead of comparing in DB. Watch it in the SQL Profiler and you will see the difference.

how to linq to sql query for getting records of two columns?

I want to get data from both tables but it shows syntax error on .ToList() that is type mismatch.
Here is my code
List<activity> ObjActivitys = new List<activity>();
ObjActivitys = (from cn in _Context.activities
join ac in _Context.activity_event on cn.id equals ac.activity_id
where cn.lead_id == id
select new { cn, ac }).ToList();
kindly help me.
You should select the Object type then:
If your activity looks like this:
public class activity
{
public activity Your_Prop1 {get;set;}
public activity_event Your_Prop2 {get;set;}
}
Then you can set Your_Prop1 and Your_Prop2 in the select statement
List<activity> ObjActivitys = new List<activity>();
ObjActivitys = (from cn in _Context.activities
join ac in _Context.activity_event on cn.id equals ac.activity_id
where cn.lead_id == id
select new activity{ Your_Prop1 = cn, Your_Prop2 = ac }).ToList();
EDIT:
If you have a one-to-many relation between acitivty and activity_event table - then the Model should look something like this:
public class activity
{
public int id {get;set;}
//other properties
//
public virtual ICollection<acitivity_event> activity_events { get; set; }
}
So when you select an activity:
var myObj = dbContext.acitivty.First(s => s.id == 1);
you should be able to access the acitivty_events like this:
var thisActivityEvents = myObj.acitivty_events.ToList();
Remove the List ObjActivitys = new List<activity>() command
and use only:
List<object> objActivitys = (from cn in _Context.activities
join ac in _Context.activity_event on cn.id equals ac.activity_id
where cn.lead_id == id
select new { cn,ac }).ToList();
Your linq query returns a list of anonymous type which you try to assign to a list of activity variable. This is why you get the type mismatch error.
You can than pass objActivitys to any other function. If you want to access the cn and ac properties , you can do something like this:
foreach(object activity in objActivitys)
{
dynamic d = activity;
// do something with d.cn
// do something with d.ac
}

Viewbag , Printing data from hashset

i want to print the viewbag recieved from the controller but i cant, my code in the controller is here:
var qry = from c in db.Customers
join o in db.Orders on id equals o.CustomerID
where id == o.CustomerID
select new {o.OrderID ,o.OrderDetails};
ViewBag.OrdersForUser = qry.ToList();
the printing code in my view is :
#foreach (var order in ViewBag.OrdersForUser)
{
#order
}
the printed text right now is:
{ OrderID = 1, OrderDetails = System.Collections.Generic.HashSet`1[FinalProject.Models.OrderDetail] }
the type of OrderID is int, the type of OrderDeatils is ICollection
i want to print the data in the hash set (and not the decleration like now) , and to split the Order Id into other space.
ViewBag is a dynamic type. And you assign an anonymous type, then you cant get its type in view side.
controller
var qry = from c in db.Customers
join o in db.Orders on id equals o.CustomerID
where id == o.CustomerID
// in this line, what is the type of list ? You should define its type
// for example:
select new SomeType{OrderId = o.OrderID ,OrderDetails = o.OrderDetails}
//select new {o.OrderID ,o.OrderDetails};
ViewBag.OrdersForUser = qry.ToList();
and then in your
view
#foreach (var order in (List<SomeType>)ViewBag.OrdersForUser)
{
#order
}
List that you return from controller, should not be anonymous type. (select new SomeType)
In view, you should define viewbag type. (List)ViewBag.OrdersForUser)
AFTER COMMENT
Or if there is relation definitions between your entities, you can get only order details like following :
controller:
ViewBag.OrdersForUser = db.OrderDetails.Where(d=>d.Order.CustomerId == id);
view :
#foreach (var orderDetail in (List<OrderDetail>)ViewBag.OrdersForUser)
{
#orderDetail.Order.xxx
}

returning multiple class model data from linq in list via return method in C#

I have LINQ output which I am trying to pass in list but I am getting following error
in linq result I am trying to pass data from two class model, if I do one class model (listOfCoursesWithoutURL ) then it work but I need to pass processedCourseInstance. I have created ModelView of two classes but not sure what I am missing in this picture
ViewModel
public class CoursesInstanceStudyLevel_ViewModel
{
public CourseInstanceModel _CourseInstanceModel { get; set; }
public StudyLevelModel _StudyLevelModel { get; set; }
}
My Class
public List<CoursesInstanceStudyLevel_ViewModel> ProcessAllCoursesApplicationURL(CourseApplicationsURLFeed_Model _obj)
{
using(var _uof = new Courses_UnitOfWork())
{
_uof.CourseInstances_Repository.GetAll();
var _listOfCoursesWithoutURL = (from b in ListOfCoursesInstances
where b.ApplicationURL == null
select b).ToList();
var processedCourseInstance = (from _courseInstances in _uof.CourseInstances_Repository.GetAll()
join _courses in _uof.Courses_Repository.GetAll() on _courseInstances.CourseID equals _courses.CourseID
join _studylevel in _uof.StudyLevel_Repository.GetAll() on _courses.StudyLevelId equals _studylevel.StudyLevelID
orderby _courseInstances.CourseCode
select new { _courseInstances, _studylevel }).ToList();
return processedCourseInstance; // it doesn't work ... refer to screen shot
// return _listOfCoursesWithoutURL //it works
}
}
Error
here:
select new { _courseInstances, _studylevel })
you are defining an anonymous object. You have a type ready, so use that one:
select new CoursesInstanceStudyLevel_ViewModel
{
_CourseInstanceModel = _courseInstances,
_StudyLevelModel = _studylevel
}
assuming CourseInstanceModel and StudyLevelModel are the correct types
With highlighted line in following code snippet, you are selecting an anonymous object instead of a concrete CourseIntaceStudyLeve_ViewModel
select new { _courseInstances, _studylevel }
You will have to change your query to following..
var processedCourseInstance = (from _courseInstances in _uof.CourseInstances_Repository.GetAll()
join _courses in _uof.Courses_Repository.GetAll() on _courseInstances.CourseID equals _courses.CourseID
join _studylevel in _uof.StudyLevel_Repository.GetAll() on _courses.StudyLevelId equals _studylevel.StudyLevelID
orderby _courseInstances.CourseCode
select new CoursesInstanceStudyLevel_ViewModel(){
_CourseInstanceModel = _courseInstances.FirstOrDefault(),
StudyLevelModel = _studylevel.FirstOrDefault()}).ToList();
I have assumed you would need only first course and first study level based on your view model definition and there for applied FirstOrDefault. You can choose to go along with this or change your view model definition.
here is my answer and it works
var processedCourseInstance =
(from _courseInstances in _uof.CourseInstances_Repository.GetAll()
join _courses in _uof.Courses_Repository.GetAll() on _courseInstances.CourseID equals _courses.CourseID
join _studylevel in _uof.StudyLevel_Repository.GetAll() on _courses.StudyLevelId equals _studylevel.StudyLevelID
orderby _courseInstances.CourseCode
select new CoursesInstanceStudyLevel_ViewModel() {
_CourseInstanceModel = _courseInstances,
_StudyLevelModel = _studylevel
}).ToList();

Get field descriptions from a parent related table in a gridview

What would be the best way to set a gridView.DataSource for LINQ query with some foreign keys and get fields in the parent tables? Like this:
The table BOOK have a Author_Id, which is related to table Author
class:
public IQueryable<Book> ListAll()
{
RENDBDataContext db = new RENDBDataContext();
var result = from b in db.Books
orderby b.Id descending
select b;
}
code-behind:
grdBooks.DataSource = vBooks.ListAll();
grdBooks.DataBind();
In the ASPX page I can get to the Author name with the [asp:TemplateField], using <%Eval("Author.Name")%>
What I'm looking for is a better solution, that doesn't involve changes in the aspx page
var result = from b in db.Books
orderby b.Id descending
select
{
AuthorName = b.Author.Name,
Title = b.Title,
etc = b.etc
};
Alternately, if you don't want to re-list every property you are going to use you could use:
var result = from b in db.Books
orderby b.Id descending
select
{
AuthorName = b.Author.Name,
Book = b
};
But then you'd have to write "Book.Title" in you r GridView. However, either way, it will get all the field you need in a single SQL statement.

Categories