I have an entity query which groups the number of property reviews to a property. However im having some trouble with the query to pull the rest of the data on the property based on its propertyID. Thanks!
Example Results:
|PropertyID | NumOfReviews | StreetAddress | City |
1 14 1600 Speaker St. Miami
Query:
var query1 = from r in db.Reviews
group r by r.propertyID into g
select new
{
propertyID = g.Key,
numofReviews = g.Count()
//Get Rest of data
};
Property Model:
public partial class Property
{
public int propertyID { get; set; }
public string streetaddress { get; set; }
public string city { get; set; }
public string zip { get; set; }
public string state { get; set; }
public string country { get; set; }
public string route { get; set; }
public virtual ICollection<Review> Reviews { get; set; }
}
Review Model:
public partial class Review
{
public int reviewID { get; set; }
public int propertyID { get; set; }
public int rating { get; set; }
public string review { get; set; }
public virtual Property Property { get; set; }
}
Can you come at it from the opposite direction?
var query = from p in db.Properties
select new {
propertyId = p.PropertyId,
numofReviews = p.Reviews.Count()
//Grab remaining properties off of the p variable that you need
};
Related
I want to retrieve all players from db for one club where they are in M:M relationship using PlayerClubs join table. My code is working but really doesn't want that approach for example, first I am retrieving all players from db
var players = await _context.PlayerClubs.Where(pc => pc.ClubId == id).Select(p => p.Player).ToListAsync();
then I retrieve the club based on id which I receive from controller
var club = await _context.Clubs.Where(z => z.Id == id).FirstOrDefaultAsync();
and lastly populate ClubViewModel with this data
return new ClubViewModel()
{
Players = players,
Club = club,
};
Now I want to populate this new ClubViewModel with just one db call i.e. one query using linq expression.
Things that I have tried
var query = (from c in _context.Clubs
join pc in _context.PlayerClubs on c.Id equals pc.ClubId
join player in _context.Players on pc.PlayerId equals player.Id
where c.Id == id
select new ClubViewModel
{
Players = player,
Club = c,
}).ToListAsync();
but I got stuck.
PlayerClubs table
Club
public class Club
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[EnumDataType(typeof(Gender))]
public Gender GenderType { get; set; }
public int SeasonId { get; set; }
public virtual Season Season { get; set; }
[Required]
public string YearOfEstablishment { get; set; }
[Required]
public string YearOfEntryIntoLeague { get; set; }
public string Note { get; set; }
[ForeignKey("League")]
public int LeagueId { get; set; }
public virtual League League { get; set; }
public virtual ICollection<PlayerClub> PlayerClubs { get; set; }
public virtual ICollection<CoachClub> CoachClubs { get; set; }
}
Player
public class Player
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string FullName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime Birth { get; set; }
public int LicenseNumber { get; set; }
public string Note { get; set; }
public virtual List<string> Clubs { get; set; }
public virtual List<Club> Klubovi { get; set; }
public virtual List<string> ClubNames { get; set; }
[StringLength(13, ErrorMessage = "Матичниот број не може да биде подолг од 13 цифри")]
public string Embg { get; set; }
public virtual ICollection<PlayerClub> PlayerClubs { get; set; }
public Player()
{
Clubs = new List<string>();
ClubNames = new List<string>();
Klubovi = new List<Club>();
}
}
PlayerClub
public class PlayerClub
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("Club")]
public int ClubId { get; set; }
[ForeignKey("Player")]
public int PlayerId { get; set; }
public virtual Club Club { get; set; }
public virtual Player Player { get; set; }
}
ClubViewModel
public class ClubViewModel : Club
{
public Club Club { get; set; }
public List<Player> Players { get; set; }
public ClubViewModel()
{
Players = new List<Player>();
}
}
Your query:
var query =
from c in _context.Clubs
where c.Id == id
select new ClubViewModel
{
Players = c.PlayerClubs.Select(pc => pc.Player).ToList(),
Club = c,
};
var result = await query.ToListAsync();
I have Order model And OrderDetails model like that:
public class Order
{
public int ID { get; set; }
public int ClientID { get; set; }
public int ShippingID { get; set; }
public int SharepointID { get; set; }
public int CallStatuID { get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
// public int OrderStatusID { get; set; }
public decimal ShippingCost { get; set; }
public string purchasetype { get; set; }
public string Notes { get; set; }
public decimal Total { get; set; }
public virtual List<OrderDetail> orderdetails { get; set; }
public virtual Client Client { get; set; }
public virtual Shipping shipping { get; set; }
public virtual Sharepoint sharepoint { get; set; }
public virtual CallStatu callStatu { get; set; }
}
and
public class OrderDetail
{
public int ID { get; set; }
public int OrderID { get; set; }
public int ItemID { get; set; }
public int SizeID { get; set; }
public decimal Price { get; set; }
public int orderStatuID { get; set; }
public int Quantity { get; set; }
public decimal Total { get; set; }
public virtual Order order { get; set; }
public virtual Item item { get; set; }
public virtual Size size { get; set; }
public virtual OrderStatu orderStatu { get; set; }
}
i want to select Client name, Governorate, Total of the Order and Items count
So i wrote this code:
public JsonResult ShareSearchDetails(SharepointANVM ANVM)
{
var SHR = from O in db.Orders
where O.SharepointID == ANVM.Id
join OD in db.OrderDetails
on O.ID equals OD.OrderID
where OD.orderStatuID == ANVM.NameOfStutes
select new
{
ClientName = O.Client.RealName,
Governorate = O.Client.Region.RegionName,
Total = O.Total,
Items = O.orderdetails.Count(),
Orderstatu = OD.orderStatu.NameOfStutes
};
return Json(SHR.ToList(), JsonRequestBehavior.AllowGet);
}
the problem is that the result is right, but its ordering by OrderDetails model.
that's the code get all rows from sub model (orderdetails) but i want it come ordering by Main model (Orders)
the result:The wrong result
but the correct Result should be like that :
The correct result
Please help
You could use Distinct to get not duplicated rows, like the following code:
var SHR = (from O in db.Orders
join OD in db.OrderDetails on O.ID equals OD.OrderID
where O.SharepointID == ANVM.Id && OD.orderStatuID == ANVM.NameOfStutes
select new
{
ClientName = O.Client.RealName,
Governorate = O.Client.Region.RegionName,
Total = O.Total,
Items = O.orderdetails.Count(),
Orderstatu = OD.orderStatu.NameOfStutes
})
.Distinct()
.ToList();
Note that, you don't need to use where twice.
I hope you find this helpful.
You can use grouping in your linq just like in SQL :
var SHR = from O in db.Orders
join OD in db.OrderDetails on O.ID equals OD.OrderID
where OD.orderStatuID == ANVM.NameOfStutes && O.SharepointID == ANVM.Id
group new { O, OD } by new {
ClientName = O.Client.RealName,
Governorate = O.Client.Region.RegionName,
Total= O.Total,
Orderstatu = OD.orderStatu.NameOfStutes
} into grp
select new
{
grp.ClientName,
grp.Governorate,
grp.Total,
grp.Orderstatu,
Items = grp.Count()
};
I am trying to get the total of each invoice in a table from the sum of the invoice items.
My invoice data model is
public class Invoice
{
[Key]
public int InvoiceId { get; set; }
public int ClientId { get; set; }
public int CustomerId { get; set; }
public string Type { get; set; }
public string Number { get; set; }
public DateTime Date { get; set; }
public bool Paid { get; set; }
public bool Printed { get; set; }
public string Notes { get; set; }
public virtual ICollection<InvoiceItem> InvoiceItems { get; set; }
public virtual Customer customer { get; set; }
}
and my invoiceitem data model is
public class InvoiceItem
{
[Key]
public int InvoiceItemId { get; set; }
public int InvoiceId { get; set; }
[StringLength(100)]
public string PartNo { get; set; }
public string Description { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public int TaxId { get; set; }
public virtual Invoice Invoice { get; set; }
}
To populate the grid I have
response.Records.Add(new JqGridRecord(Convert.ToString(x.Invoice.InvoiceId), new InvoiceEditViewModel()
{
Id = x.Invoice.InvoiceId,
CustomerName = x.Customer.Name,
Total = x.Invoice.InvoiceItems.Where(p => p.InvoiceId == x.Invoice.InvoiceId).Sum(d => d.Price * d.Quantity ),
InvType = x.Invoice.Type,
Notes = x.Invoice.Notes,
Date = x.Invoice.Date.ToShortDateString(),
Number = x.Invoice.Number,
Printed = x.Invoice.Printed,
}));
}
However, this throws an error when calculating the total
"There is already an open DataReader associated with this Command which must be closed first"
I would appreciate how to resolve this one.
Seems that what I needed was to add
MultipleActiveResultSets=true;
In my connection string.
I'm using Code First and LINQ to SQL in an ASP.NET MVC4 project. In the below query I'm trying to populate PatientView.Appointments.ScheduledBy, but it's returning null. I've tried adding .Include("Appointments.ScheduledBy"), but Appointments.ScheduledBy continues to return null.
How can I modify the LINQ to SQL expression to get ScheduledBy populated?
Here's my LINQ to SQL (Id is the action's parameter)
var q = from p in context.Patients.Include("Appointments.ScheduledBy")
where p.Id == Id
select new PatientView
{
Patient = p,
Appointments = p.Appointments.OrderByDescending(a => a.ScheduledFor)
};
PatientView pv = q.Single();
PatientView is the view model for the view. The Appointments property does get populated, but the Appointments' ScheduledBy property is null.
public class PatientView
{
public Patient Patient { get; set; }
public IEnumerable<Appointment> Appointments { get; set; }
}
public class Patient
{
public int Id { get; set; }
public string Number { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Appointment> Appointments { get; set; }
}
public class Appointment
{
public int Id { get; set; }
public Patient Patient { get; set; }
public Employee ScheduledBy { get; set; }
public DateTime ScheduledFor { get; set; }
}
public class Employee
{
public int Id { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
I can't understand what i'm doing wrong. Every time I'm getting this error:
The entity or complex type 'BusinessLogic.CompanyWithDivisionCount' cannot be constructed in a LINQ to Entities query.
I need to get info from 'Company' table and divisions count of each company from 'Division' table, and then make PagedList. Here is my 'Company' table:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using BusinessLogic.Services;
using BusinessLogic.Models.ValidationAttributes;
namespace BusinessLogic.Models
{
public class Company
{
public Company()
{
Country = "US";
Status = true;
}
public int Id { get; set; }
[Required]
[UniqueCompanyName]
public string Name { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public int Zip { get; set; }
public string Country { get; set; }
public string ContactInfo { get; set; }
[Required]
public DateTime EffectiveDate { get; set; }
public DateTime TerminationDate { get; set; }
public bool Status { get; set; }
[Required]
public string URL { get; set; }
public string EAP { get; set; }
public string EAPCredentials { get; set; }
public string BrandingColors { get; set; }
public string Comments { get; set; }
}
}
Here is my domain model:
public class Company
{
public Company()
{
Country = "US";
Status = true;
}
public int Id { get; set; }
[Required]
[UniqueCompanyName]
public string Name { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public int Zip { get; set; }
public string Country { get; set; }
public string ContactInfo { get; set; }
[Required]
public DateTime EffectiveDate { get; set; }
public DateTime TerminationDate { get; set; }
public bool Status { get; set; }
[Required]
public string URL { get; set; }
public string EAP { get; set; }
public string EAPCredentials { get; set; }
public string BrandingColors { get; set; }
public string Comments { get; set; }
}
public class CompanyWithDivisionCount: Company // I'm using this
{
public int DivisionCount { get; set; }
}
Here is my controller:
public ActionResult CompaniesList(int? page)
{
var pageNumber = page ?? 1;
var companies = companyService.GetCompaniesWithDivisionsCount2();
var model = companies.ToPagedList(pageNumber, PageSize);
return View(model);
}
And here is my service part:
public IQueryable<CompanyWithDivisionCount> GetCompaniesWithDivisionsCount2()
{
return (from c in dataContext.Companies.AsQueryable()
select new CompanyWithDivisionCount
{
Id = c.Id,
Name = c.Name,
Status = c.Status,
EffectiveDate = c.EffectiveDate,
URL = c.URL,
EAP = c.EAP,
EAPCredentials = c.EAPCredentials,
Comments = c.Comments,
DivisionCount = (int)dataContext.Divisions.Where(b => b.CompanyName == c.Name).Count()
});
}
}
Thanks for help!!!
Creator of PagedList here. This has nothing to do with PagedList, but rather is an Entity Framework issue (I'm no expert on Entity Framework, so can't help you there). To confirm that this is true, write a unit test along the following lines:
[Test]
public void ShouldNotThrowAnException()
{
//arrange
var companies = companyService.GetCompaniesWithDivisionsCount2();
//act
var result = companies.ToList();
//assert
//if this line is reached, we win! no exception on call to .ToList()
}
I would consider changing you data model if possible so that instead of relating Companies to Divisions by name strings, instead use a properly maintained foreign key relationship between the two objects (Divisions should contain a CompanyID foreign key). This has a number of benefits (including performance and data integrity) and will almost certainly make your life easier moving forward if you need to make further changes to you app (or if any company ever decides that it may re-brand it's name).
If you create a proper foreign key relationship then your domain model could look like
public class Company
{
...
public virtual ICollection<Division> Divisions{ get; set; }
public int DivisionCount
{
get
{
return this.Divisions.Count()
}
}
...
}