I am new to Entity Framework, can anybody please tell how to extract data from following query and pass the result to the view.
public ActionResult Index()
{
var query = (from c in db.Customers
join b in db.Banks on c.Id equals b.CustomerId
join bt in db.BankTransactions on b.Id equals bt.BankId
where c.Id == 1
orderby bt.Id descending
select new
{
Name = c.Name,
Balance = bt.Balance
}).Take(1);
//I want to pass Customer Name and Customer Balance to the view
return View();
}
Create a view model
public class CustomerVM
{
public string Name { get; set; }
public decimal Balance { get; set; }
}
and modify your query to
var query = (from c in db.Customers ...
....
select new CustomerVM
{
Name = c.Name,
Balance = bt.Balance
}).FirstOrDefault();
then
return View(query);
View
#model YourAssembly.CustomerVM
...
#Html.DisplayFor(m => m.Name)
...
I didn't compile this snipet to check, but to solve your problem you could do something like this:
NewObject balanceInfo = query.AsEnumerable().Select(p => new NewObject
{
CostumerName = p.Name,
CostumerBalance = p.Balance
});
I do it a lot when my methods return lists. As I told, I didn't make a query and compiled to test, but I believe that this should solve your problem.
Related
I have this query running ok in a stored procedure but now I want to do what sp does from c# with EF and linq, any idea?
I'm using .Net 6 in MVC EF project.
I have my db context working and entities for Productos and AlmacenesStock created
The query:
SELECT s.ProductoId, p.Descripcion, SUM(s.Cantidad) AS Cantidad
FROM Productos p INNER JOIN AlmacenesStock s
ON p.Id = s.ProductoId
GROUP BY s.ProductoId, p.Descripcion
Thanks!
Assume that in your DbContext you have these DbSet:
public DbSet<Producto> Productos { get; set; }
public DbSet<AlmacenesStock> ProductoAlmacenesStocks { get; set; }
With LINQ query syntax/expression which has some similarities with SQL query.
var result = (from a in _context.Productos
join b in _context.AlmacenesStocks on a.Id equals b.ProductoId
group new { a, b } by new { b.ProductoId, a.Descripcion } into g
select new
{
ProductoId = g.Keys.ProductoId,
Descripcion = g.Keys.Descripcion,
Cantidad = g.Sum(x => x.b.Cantidad)
}
)
.ToList();
The above result will return the value with the List of anonymous type. If you have your concrete class to store the value, modify the select part as:
select new YourEntity
{
ProductoId = g.Keys.ProductoId,
Descripcion = g.Keys.Descripcion,
Cantidad = g.Sum(x => x.b.Cantidad)
}
Recommended reading: Query expression basics
Make sure you set up the relationship of Products and AlmacenesStock
var products = _context.Products.Include(product => product.AlmacenesStock)
.GroupBy(product => new { product.ProductId, product.Description }
.Select(product => new { product.Key.ProductId, product.Key.Description, x.Sum(almnacenesStock => almnacenesStock.Cantidad) });
What I'm trying to do is to is join tables to fill a viewModel that looks like this:
public class UserViewModel
{
public String Id { get; set; }
public String UserName { get; set; }
public String Email { get; set; }
public String Role { get; set; }
}
My query atm looks like this, but it doesn't work obviously, but it might help with descriping the problem.
public IActionResult AddAdmin()
{
var allUsers = (from u in _dbContext.Users
join r in _dbContext.UserRoles on u.Id equals r.UserId
join i in _dbContext.Roles on r.RoleId equals i.Id
select new UserViewModel
{
UserName = u.UserName,
Email = u.Email,
Id = u.Id,
Role = i.Name
}).ToList();
return View(allUsers);
}
As you see the thing I find hard is to apply the role to the viewModel, since they are connected to eachother with a manyTomany Table
Problem: The query does not work, and does not give anything in result
Before I joined the role into the viewModel, i got the data to the view, now i get nothing at all.
My Question: What's the correct way to do this? To easily navigate through the data
When I did it like this, it worked...
public IActionResult AddAdmin()
{
var allUsers = (from u in _dbContext.Users
select new UserViewModel
{
UserName = u.UserName,
Email = u.Email,
Id = u.Id
}).ToList();
foreach (var item in allUsers)
{
var roleId = _dbContext.UserRoles.Where(x => x.UserId == item.Id).FirstOrDefault();
item.Role = _dbContext.Roles.Where(x => x.Id == roleId.RoleId).FirstOrDefault().Name;
}
return View(allUsers);
}
I know it looks like s***..
You need a third entity to tie the two together. In Database terms, it is called a junction table.
select TeamName, [Description], COUNT(u.UserId)
from Team t
left outer join [User] u on u.TeamId=t.TeamId
group by TeamName, Description, UserId
and here i have so far but cant able to do that.please help
var countUser = (from t in db.Teams
join u in db.Users on u.TeamId equals t.TeamId
group TeamName, Description, UserId by select
new
{
u.UserId
}).Count();
This should do it:
Teams.Join(Users.DefaultIfEmpty().
t => t.TeamId,
u => u.TeamId,
(t, u) => new { t.TeamName, t.Description, UserId = u == null ? null:(int?)u.UserId })
.GroupBy(x => x)
.Select(g => new { g.Key.TeamName, g.Key.Description, Count = g.Count() });
RePierre I'm going to steal part of your answer (+1) because I think I understand what OP is talking about, though the question text does not convey it.
You could do something like this:
// Model class for View
public class UsersPerTeamCount
{
public string TeamName { get; set; }
public string Description { get; set; }
public int Count { get; set; }
}
// ...
public ActionResult PlayersPerTeam()
{
var model = from t in db.Teams
join u in db.Users on t.TeamId equals u.TeamId into joinedRecords
select new UsersPerTeamCount()
{
Name = t.TeamName,
Description = t.Description,
PlayerCount = joinedRecords.Count()
};
return View(model);
}
As far as in OPs comment "please try to write as like..." that's just a difference in syntax, it doesn't really matter which way you write it - either fluent vs query syntax (at least i think it's called query syntax)
friend i'm working in Linq. I use join in linq query with Entity Model as below.
var Records = from Cats in Context.Categories
join prod in Context.Products on Cats.Id equals prod.Category_Id
select new { CatName = Cats.Name, ProdName = prod.Name };
i want to convert the Record var in List of object, so i create a intermediate object which hold both entites values(product,category). Now when i cast this var to list like
List<test> testList = (List<test>)Records;
as Record.ToList(); is compiler error. how i cast the var object to list in order to bind it with listview in frontend. Is there any alternative in lambda which will be also appreciated. Is my approach is right?
my test class is as:
class test{
string catname;
string productname;
}
use ToList() on your query.
var Records = (from Cats in Context.Categories
join prod in Context.Products on Cats.Id equals prod.Category_Id
select new test { CatName = Cats.Name, ProdName = prod.Name }).ToList();
In order to make it work you need to define your test class as follows (you need to define properties)
public class test {
public string catname {get;set;}
public string productname {get;set;}
}
Create new Test and set the properties accordingly and finally call ToList
List<test> testList = (from c in Context.Categories
join p in Context.Products on c.Id equals p.Category_Id
select new Test{ Category= c, Product= p}).ToList();
If have class like below
public class Test{
public string CatName{ get; set; }
public string ProductnName{ get; set; }
}
List<test> testList = (from c in Context.Categories
join p in Context.Products on c.Id equals p.Category_Id
select new Test{ CatName= c.Name, ProductnName= p.Name}).ToList();
I'm newer using C#, linq. I'm trying to add the UserName into a query to show it as part of a DataSource of a ListView, I have tested several way to joined, but always I m'receiving next error:
"Unable to create a constant value of type 'Web.Admin.system.User'. Only primitive types or enumeration types are supported in this context."
My code is:
//Entities
public class Category
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Order
{
public Guid Id { get; set; }
public string Description { get; set; }
public Guid CategoryId { get; set; }
public Guid UserId { get; set; }
}
//class added just for getting the user list (possibly, I do not need)
public class User
{
public Guid Id { get; set; }
public String Name { get; set; }
}
Here is my code preparing the filter
//retrieve the data from Order and Category
IQueryable<Order> orders = orderService.GetAllOrders();
IQueryable<Category> category = categoryService.GetAllCategories();
//obtain the users
MembershipUserCollection members = Membership.GetAllUsers();
// 1st option for managing users directly with memberShip variable
var memberShip = members.Cast<MembershipUser>().ToDictionary(m => m.ProviderUserKey, m => m.UserName).AsQueryable();
// 2nd option, I have added this code to see if I could manage the users as a list
List<User> users = new List<User>();
foreach (var _member in memberShip)
{
users.Add(new User { Id = (Guid)_member.Key, Name = _member.Value });
}
//Getting information to fill a listview
var DDLsource = from i in orders
join c in category on i.CategoryId equals c.Id
join u in users on i.UserId equals u.Id // 1st I tried to use memberShip directly but gave me error of types
select new
{
i.Id,
i.Description,
CategoryName = c.Name,
UserName = u.Name
};
ListViewOrders.DataSource = DDLsource.ToList();
Here is where the Error is triggered, I'm trying to understand the error and do other solution, I tested the query like:
Example 2
var DDLsource = from i in orders
join c in category on i.CategoryId equals c.Id
select new
{
i.Id,
i.Description,
CategoryName = c.Name,
UserName = (from u in users where u.Id == i.UserId select u.Name)
};
Example 3
var DDLsource = from i in orders
join c in category on i.CategoryId equals c.Id
join u in Membership.GetAllUsers().Cast<MembershipUser>() on i.UserId equals ((Guid)u.ProviderUserKey)
select new
{
i.Id,
i.Description,
CategoryName = c.Name,
UserName = u.UserName
};
all with the same results, could someone give me a hand with my mistake will surely be very obvious. Thanks in advance
I would do something like this (sorry, untested code...):
var DDLsource =
from i in orders
join c in category on i.CategoryId equals c.Id
select new
{
i.Id,
i.Description,
CategoryName = c.Name,
i.UserId,
UserName = ""
};
foreach(var ddl1 in DDLsource)
ddl1.UserName = Membership.GetUser(ddl1.UserId).Name;