How do i merge these queries into 1 - c#

So i have below queries.
I would really like to merge these into 1 query.
Next to the fact that this results in an empty collection (which it shouldn't)
My brain just imploded when i tried making this into 1 query.
So if it's not clear from the code
I want to select all horses from a certain user. that have not been signed up for the race that the user is trying to sign up for.
var userhorses = (from h in entities.Horses
where h.UserId == id
select h);
var race = (from r in entities.Races
where r.Id == id
select r).Single();
var runninghorses = (from rh in race.RacingHorses
where rh.UserId == id
select rh);
var nonracinghorses = (from nrh in userhorses
from rh in runninghorses
where nrh.Id != rh.Id
select nrh).ToList();
EDIT
public class Horse
{
[Key]
public int Id { get; set; }
public int? UserId { get; set; }
public virtual User Owner { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
public int? GenderId { get; set; }
public virtual Gender Gender { get; set; }
public int? ColorId { get; set; }
public virtual Color Color { get; set; }
public int? LegTypeId { get; set; }
public virtual LegType LegType { get; set; }
public int? CharacterId { get; set; }
public virtual Character Character { get; set; }
public int Hearts { get; set; }
public bool Retired { get; set; }
public bool CPU { get; set; }
public bool ForSale { get; set; }
public int ListPrice { get; set; }
public DateTime? Deadline { get; set; }
// Parents
public int? SireId { get; set; }
public virtual Horse Sire { get; set; }
public int? DamId { get; set; }
public virtual Horse Dam { get; set; }
// Internals
public int Stamina { get; set; }
public int Speed { get; set; }
public int Sharp { get; set; }
// Special
public int Dirt { get; set; }
// Externals
public int Start { get; set; }
public int Corner { get; set; }
public int OutOfTheBox { get; set; }
public int Competing { get; set; }
public int Tenacious { get; set; }
public int Spurt { get; set; }
//Future
public virtual ICollection<Race> FutureRaces { get; set; }
//RaceResults
public virtual ICollection<RaceResult> RaceResults { get; set; }
//Training
public virtual ICollection<Training> TrainingResults { get; set; }
//Bids
public virtual ICollection<Bid> Bids { get; set; }
public Horse() {
ForSale = false; //default value
Deadline = null;
}
}
public class Race
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
[Required(ErrorMessage = "Purse is required")]
public int Purse { get; set; }
[Required(ErrorMessage = "Slots are required")]
public int Slots { get; set; }
public int SlotPrice { get; set; }
public DateTime? RaceTime { get; set; }
//public int? TrackId { get; set; }
//public virtual Track Track { get; set; }
public int? OwnerId { get; set; }
public virtual User Owner { get; set; }
public virtual ICollection<Horse> RacingHorses { get; set; }
public virtual ICollection<RaceResult> RaceResults { get; set; }
public Race()
{
SlotPrice = 0; //default value
Slots = 8;
}
}

Have you considered using the "let" keyword?
http://msdn.microsoft.com/en-us/library/bb383976.aspx
It also seems you could take benefit of the "except" functionality
http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
(Since I don't have the reputation to make a comment, why are you reusing the variable "id" for both User and identifying a race?)
Additional suggestion is you can filter inside the Single
var race = entities.Races.Single(r => r.Id == raceId);

I am making these assumptions:
you have id, the user ID
you have raceId, the ID of the race being signed up for
there is an entities.RacingHorses collection which is the associations of race and horse IDs
Then you could use:
from h in entities.Horses
where h.UserId == id
let rhs = entities.RacingHorses.Where(rh => rh.HorseId == h.Id)
where !rhs.Any(rh => rh.RaceId == raceId)
select h
Breakdown:
h = a user's horse
rhs = RacingHorses associations for h
if raceId appears in rhs, then h is signed up for that race; do not select this h

all kudo's go to nmclean for this one.
public static SelectList GetNonRacingHorses(int id, int raceId)
{
HorseTracker entities = new HorseTracker();
var race = entities.Races.Single(r => r.Id == raceId);
var racehorses = from h in race.RacingHorses
select h.Id;
var userhorses = (from h in entities.Horses
where
h.UserId == id
orderby h.Name
select h);
var nonracinghorses = from h in userhorses
where !racehorses.Contains(h.Id)
select h;
List<SelectListItem> sli = new List<SelectListItem>();
foreach (Horse horse in nonracinghorses)
{
sli.Add(new SelectListItem { Text = horse.Name, Value = horse.Id.ToString(), Selected = false});
}
return new SelectList(sli, "Value", "Text");
}

Related

Selection for Linq Query

How can I select the List of ExtrasName and ExtrasId in the following query.
The query contains some mathematical operations aswell.
var query =
from a in _context.Cities
from b in a.CityExtras
where a.CityId == CityId && extraIds.Contains(b.ExtrasId)
group new { a, b } by new { a.PricePerSqM , a.Name, a.CityId , } into g
select new
{
City = g.Key.Name,
PricePerSqM = g.Key.PricePerSqM,
TotalPrice = g.Sum(x => x.b.Price) + g.Key.PricePerSqM * squareMeter
};
My Models are:
public class Extras
{
public int ExtrasId { get; set; }
[Required]
public string ExtrasName { get; set; }
public ICollection<CityExtras> CityExtras { get; set; }
}
public class City
{
public int CityId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int PricePerSqM { get; set; }
public ICollection<CityExtras> CityExtras { get; set; }
}
public class CityExtras
{
public int CityId { get; set; }
public City City { get; set; }
public Extras Extras { get; set; }
public int ExtrasId { get; set; }
public int Price { get; set; }
}
I need ExtrasNames and ExtrasId in the query
As they stand, your models are not going to allow you to do this easily. You should add navigation properties to your models, then your Linq will be much cleaner (no need for the double select), and you will be able to navigate upwards to the Extra object and get the data you want.

How to join two tables and fetch data from

I have two tables from which I want to fetch the data and return it to the API for consumable purposes. There is a relationship between the two tables.
[![enter image description here][1]][1]
When I try to fetch the data, it is returning only one row which is not what I want.
How can I return all the data related to ResellerId (8435 examples)?
This is my code:
public RateSheetModel GetRateSheet(int resellerId)
{
// This only returns only one row.
// How can I get all rows for all the same Id?
var rateSheetDetails = (from r in _Context.WholesaleRateSheet
where r.ResellerId == resellerId
select r).First();
}
Models
public class WholesaleRateSheetMarkup
{
[Key]
public int RateSheetMarkupId { get; set; }
[Required]
public int ResellerId { get; set; }
[StringLength(50)]
public string RatesheetName { get; set; }
}
public class WholesaleRateSheet
{
[Key]
public int RateSheetId { get; set; }
[Required]
public int RateSheetMarkupId { get; set; }
[Required]
public int ResellerId { get; set; }
public string CountryCode { get; set; }
public string Description { get; set; }
public decimal Peak { get; set; }
public bool IsSouthAfricanRate { get; set; }
public bool IsInertnationRate { get; set; }
public bool IsSpecificRate { get; set; }
public int DestinationGroupSetId { get; set; }
public int DestinationGroupId { get; set; }
public string DestinationLookup { get; set; }
public DateTime CreatedDate { get; set; }
public string CreatedByUsername { get; set; }
public DateTime LastUpdatedDate { get; set; }
public string UpdatedByUsername { get; set; }
}
var rateSheetDetails = (from r in _Context.WholesaleRateSheet
join rateSheet in _Context.<tableName> on r.ResellerId equals rateSheet.ResellerId
where r.ResellerId == resellerId
select new { foo });
You're making a new type by doing this, as a combination of data from both tables. You can either define a model class and use something like
select new MyClass {
Foo = r.RateSheetMarkupId,
Bar = rateSheet.RateSheetName
}
Otherwise, no class definition is required. Simply using 'new' without a class will create an anonymous type with properties that match what you're selecting. The example here could be more precise if you share the entity names.
Altogether, going off your code:
public List<RateSheetModel> GetRateSheet(int resellerId)
{
var rateSheetDetails = (from r in _Context.WholesaleRateSheet
join m in _Context.RateSheetMarkup on r.ResellerId equals m.ResellerId
where r.ResellerId == resellerId
select new RateSheetModel {
ResellerId = r.ResellerId
RatesheetName = m.RatesheetName
};
return rateSheetDetails.ToList<RateSheetModel>;
}
public RateSheetModel { //dunno what this model looks like, but example
public int ResellerId {get; set;}
public string RatesheetName {get; set;}
}

How to get data from child to parent entity framework core?

I have two table like this -
public class Job
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime AddedTime { get; set; } = DateTime.Now;
public DateTime LastEdit { get; set; } = DateTime.Now;
public string Explanation { get; set; }
public string PhotoString { get; set; }
public bool isActive { get; set; } = true;
public int CompanyId { get; set; }
public Company Company { get; set; }
}
and company -
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Explanation { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public string PhotoString { get; set; }
public bool isActive { get; set; } = true;
public int AppUserId { get; set; }
public AppUser AppUser { get; set; }
public List<Job> Jobs { get; set; }
}
I only want to get AppUserId from Company and all Jobs from every Company. I tried this and it gave me error.
using var context = new SocialWorldDbContext();
return await context.Jobs.Where(I => I.isActive == true && I.Company.isActive).Include(I=>I.Company.AppUserId).ToListAsync();
So my question is there any way I can get this data from parent?
Include adds whole entities to the output. To add just one property use Select, something like
context.Jobs
.Where(I => I.isActive == true && I.Company.isActive)
.Select(e => new {Job=e, CompanyAppUserId = e.Company.AppUserId})
.ToListAsync();

Calculate Account Receivables using LINQ

How to calculate account receivable using LINQ.
I have tried this but stuck here.
I have done this in SQL but I want this in LINQ so I can use it in my MVC project.
var sale = saleslist.GroupBy(s => s.BuyerId).Select(s => s.Sum(u => u.Amount)).ToList();
var receipt = receiptslist.GroupBy(r => r.StakeHolderId).Select(t => t.Sum(u => u.Amount)).ToList();
List<AccountReceivablesVM> res = db.StakeHolders
.Where(r=>r.StakeHolderTypeId == "0b85a69e-55f2-4142-a49d-98e22aa7ca10")
.Select(rvm => new AccountReceivablesVM
{
CompanyName = rvm.CompanyName,
Receivables = //don't know what to do here
}).ToList();
Models:
public class StakeHolder
{
public string StakeHolderId { get; set; }
public string CompanyName { get; set; }
public string Address { get; set; }
public string Contact { get; set; }
public string StakeHolderTypeId { get; set; }
}
public class Sale
{
public string SaleId { get; set; }
public string RefNo { get; set; }
public DateTime Date { get; set; }
public string BuyerId { get; set; }
public string Description { get; set; }
public Nullable<double> Amount { get; set; }
}
public class PaymentsAndReceipt
{
public string PaymentAndReceiptId { get; set; }
public Nullable<int> VoucherNo { get; set; }
public DateTime Date { get; set; }
public string StakeHolderId { get; set; }
public string Description { get; set; }
public Nullable<double> Amount { get; set; }
}
public class AccountReceivablesVM
{
public string CompanyName { get; set; }
public Nullable<double> Receivables { get; set; }
}
Expected Result:
You can join first with stakeholderId and then sum the amount and then group by with company name and stakeholder id, however I write the code in Linq. I have considered the stakeholderid as the primary key of your table just because you have not mentioned the schema of stakeholder so.
var result = from s in db.StakeHolders
join pr in db.PaymentsAndReceipt on s.StakeHolderId equals pr.StakeHolderId
where StakeHolderTypeId == "0b85a69e-55f2-4142-a49d-98e22aa7ca10"
group s by new { s.StakeHolderId,s.CompanyName} into p
select new
{
StakeHolderId= p.Key.StakeHolderId,
CompanyName= p.Key.CompanyName,
Receivables = string.Format("{0:C}", p.Sum(y => y.Amount))
};

Convert SQL to C# Entity Framework Linq

What i am essentially trying to do is get all of the packages that have NOT been assigned a package location price for a specific location...
I have the following SQL:
SELECT * FROM Package
LEFT JOIN PackageLocationPrices ON Package.Id = PackageLocationPrices.PackageId
Where PackageLocationPrices.LocationId IS NULL
How can i convert this into Linq to entities?
I have tried something like this:
this.db.Packages.Include(p => p.PackageLocationPrices).Where(p => p.Id == p.PackageLocationPrices.????).ToList();
I am able to join package location prices but i am unable to get the properties of the packagelocationprices to do the SQL above? Below is my schema...The PackageLocationPrices.PackageId is a foreign key of Package.Id
Package Entitiy:
public partial class Package
{
public Package()
{
this.DiscountCodes = new HashSet<DiscountCode>();
this.PackageLocationPrices = new HashSet<PackageLocationPrice>();
this.Memberships = new HashSet<Membership>();
}
public int Id { get; set; }
public string Name { get; set; }
public int PackageOrder { get; set; }
public int PackageTypeId { get; set; }
public int PackagePeriodDays { get; set; }
public int PackagePeriodMonths { get; set; }
public int PackageSuspensionLimit { get; set; }
public int PackageSuspensionLimitIfAdminOverride { get; set; }
public int PackageSuspensionMinLength { get; set; }
public int PackageSuspensionMaxLength { get; set; }
public int PackageSuspensionsMaxLengthCombined { get; set; }
public int PackagePaymentHolidayLimit { get; set; }
public int PackagePaymentHolidayMinLength { get; set; }
public int PackagePaymentHolidayMaxLength { get; set; }
public int PackageVisitLimit { get; set; }
public bool PackageIsActive { get; set; }
public bool PackageIsReoccuring { get; set; }
public bool PackagePayInFull { get; set; }
public bool PackageIsSession { get; set; }
public System.DateTime CreatedDate { get; set; }
public System.DateTime ModifiedDate { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public virtual AspNetUser AspNetUserCreatedBy { get; set; }
public virtual AspNetUser AspNetUserModifiedBy { get; set; }
public virtual ICollection<DiscountCode> DiscountCodes { get; set; }
public virtual PackageType PackageType { get; set; }
public virtual ICollection<PackageLocationPrice> PackageLocationPrices { get; set; }
public virtual ICollection<Membership> Memberships { get; set; }
}
Package Location Price Entity:
public partial class PackageLocationPrice
{
public int Id { get; set; }
public int LocationId { get; set; }
public int PackageId { get; set; }
public decimal MonthlyPrice { get; set; }
public decimal TotalPrice { get; set; }
public System.DateTime CreatedDate { get; set; }
public System.DateTime ModifiedDate { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public virtual AspNetUser AspNetUserCreatedBy { get; set; }
public virtual AspNetUser AspNetUserModifiedBy { get; set; }
public virtual Location Location { get; set; }
public virtual Package Package { get; set; }
}
var result = (from p in Package
join q in PackageLocationPrices on p.Id equals q.PackageId into pq
from r in pq.DefaultIfEmpty()
select new {p, r}).ToList();
This should return something exactly like your SQL query.
I think you can create your query from another perspective:
var query=(from pl in db.PackageLocationPrices
where pl.LocationId == null
select pl.Package).ToList();
If you have disabled lazy loading then also need to use the Include extension method:
var query=(from pl in db.PackageLocationPrices.Include(p=>p.Package)
where pl.LocationId == null
select pl.Package).ToList();
Using method syntax would be this way:
var query=db.PackageLocationPrices.Include(p=>p.Package)
.Where(pl=>pl.LocationId == null)
.Select(pl=>pl.Package)
.ToList();
If you want as result both Package and PackageLocationPrice, then do this:
var query=db.PackageLocationPrices.Include(p=>p.Package)
.Where(pl=>pl.LocationId == null)
.ToList();
With this last query your are going to get a list of PackageLocationPrice, and if you want see the related Package for a givenPackageLocationPrice, you can use the Package navigation property.

Categories

Resources