calculating values in Linq deferred linq statment - c#

I am trying to optimize this piece of code this piece of code takes about 50 seconds to call. what this needs to do is get a total score from item.score and the achieved score from item.score if condition.isFound == false. Any help you guys can give would be fantastic
var myscore = from inspection in roomInspections
from RoomItemInspection in db.Table<RoomItemInspection>()
where RoomItemInspection.roomInspectionId == inspection.id
from RoomItemConditionInspection condition in db.Table<RoomItemConditionInspection>()
where condition.roomItemInspectionId == RoomItemInspection.id
from FloorRoom floorRoom in db.Table<FloorRoom>()
where floorRoom.id == RoomItemInspection.roomItemId
from room myRoom in db.Table<room>()
where myRoom.id == floorRoom.roomId
from RoomItem roomItem in db.Table<RoomItem>()
where roomItem.roomId == myRoom.id
from item myItem in db.Table<item>()
where myItem.id == roomItem.itemId
select new {score = myItem.Score, isFound = condition.isFound};
//This is the slow part of the code
totalScore = myscore.Sum (s => s.score);
score = myscore.Sum (s => s.isFound ? s.score : 0);
if(totalScore == 0)
return 0;
score = score / totalScore * 100f;
return score = (float)Math.Round (score, 1);
Here are the classes involved
public class room
{
[PrimaryKey, AutoIncrement]
public int PKId { get; set; }
public int id { get; set; }
public string name { get; set; }
public DateTime dateCreated { get; set; }
public DateTime dateModified { get; set; }
}
public class RoomItem
{
[PrimaryKey, AutoIncrement]
public int PKId { get; set; }
public int id { get; set; }
public int roomId { get; set; }
public int itemId { get; set; }
public bool isHidden { get; set; }
public bool isAlways { get; set; }
public DateTime dateCreated { get; set; }
public DateTime dateModified { get; set; }
}
public class item
{
[PrimaryKey, AutoIncrement]
public int PKId { get; set; }
public int id { get; set; }
public string name { get; set; }
public int Score { get; set; }
public DateTime dateCreated { get; set; }
public DateTime dateModified { get; set; }
}
public class RoomItemConditionInspection
{
[PrimaryKey, AutoIncrement]
public int PKId { get; set; }
public int id { get; set; }
public int conditionId { get; set; }
public int roomItemInspectionId { get; set; }
public bool isFound { get; set; }
public bool isSynced { get; set; }
public DateTime dateCreated { get; set; }
public DateTime dateModified { get; set; }
}

You shuld join by fields with PK, FK, or indexses. In your code you do joins by simple fields, without indexes, thats leeds to full scan of decart multiplication of your tables

Related

Getting Value for table_id

I have 2 tables SaleMaster
public class SaleMaster
{
public int Id { get; set; }
public List<Installments> Installments { get; set; }
}
public class Installments
{
public int Id { get; set; }
public decimal Amount { get; set; }
public DateTime Month { get; set; }
public bool IsPaid { get; set; }
}
Now I want to get the all the Installments with pending due dates,
but I also want to include the SaleMaster ID from Installment table so I can navigate back.
List<Installments> instalment = con.DbSetInstallments
.Where(x => x.Month < d && x.IsPaid == false)
.ToList();
Now I want to take SaleMaster from this list of which Installments are due.
You can add a relational property to SaleMaster in Installments:
public class Installments
{
public int Id { get; set; }
public decimal Amount { get; set; }
public DateTime Month { get; set; }
public bool IsPaid { get; set; }
public int SaleMasterId { get; set; }
public virtual SaleMaster SaleMaster { get; set; }
}
This way you have easy access to the SaleMaster's Id.

C# Linq-to-Entities OrderByDescending isn't working

Here is my entity called SportTeam:
public class SportTeam : BaseEntity
{
public int Id { get; set; }
public int SportId { get; set; }
public int TeamId { get; set; }
public int TotalPlays { get; set; }
public int TotalWins { get; set; }
public int TotalDefeats { get; set; }
public int TotalDraws { get; set; }
public float WinPercentage { get; set; }
public float Score { get; set; }
// navs
public virtual Ladder Ladder { get; set; }
public int? LadderId { get; set; }
public virtual Sport Sport { get; set; }
public virtual Team Team { get; set; }
public ICollection<Match> HomeMatches { get; set; }
public ICollection<Match> RivalMatches { get; set; }
public ICollection<Match> VictorMatches { get; set; }
public virtual ICollection<TeamMember> TeamMembers { get; set; }
public virtual ICollection<Tournament> Tournaments { get; set; }
public override bool Equals(object obj)
{
SportTeam sportTeam = (SportTeam)obj;
if (sportTeam.Id == Id)
return true;
else
return false;
}
public override int GetHashCode()
{
return 2108858624 + Id.GetHashCode();
}
}
I am trying to sort the SportTeam entity by score by doing this
List<SportTeam> sportTeams =
dbContext.SportTeams
.Where(st => st.SportId == sportTeam.SportId)
.OrderByDescending(st => sportTeam.Score)
.ToList();
However when I add a watch over the sportTeams list, the list doesn't appear to be ordered by score at all. I just get an as in representation of the table.
Any hints?
You are sorting on a constant value (sportTeam.Score) Try
OrderByDescending(st => st.Score)
instead of
OrderByDescending(st => sportTeam.Score)

How to join two table values in Sqlite Xamarin form?

I have created two models Outlet_model and TbTrdDocModel in my Xamarin from C#.
I can access the values from each model separately but now I want to join both tables in SQLite.
Do anybody know how to join these two model to access the data in the listview? Thanks in Advance.
try this
public class MusicItems
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public String Name { get; set; }
public String Tension { get; set; }
public String Category { get; set; }
public String Subcategory { get; set; }
public int ResId { get; set; }
public int LoopStart { get; set; }
}
public class Playlist
{
public String Name { get; set; }
public int ResId { get; set; }
public int LoopStart { get; set; }
}
public class Themes
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public String ThemeName { get; set; }
public String ThemeDesc { get; set; }
public int ThemeImg { get; set; }
public String ThemeCategory { get; set; }
public String ThemeSubcategory { get; set; }
}
public class MusicInThemes
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public int ResId { get; set; }
public int ThemeId { get; set; }
}
The query:
return database.Table<MusicItems>()
.Join(database.Table<MusicInThemes>().Where(t => t.ThemeId == ThemeID)
,m =>m.ResId
,t => t.ResId
,(m,t) => new {mym = m, myt = t })
.Select(a => new Playlist
{
Name = a.mym.Name,
ResId = a.mym.ResId,
LoopStart = 0
})
.ToList();

LINQ: Group by and Join

I have 2 models:
public partial class Movie
{
public Movie()
{
TimeTables = new HashSet<TimeTable>();
}
[Key]
public int MovieId { get; set; }
public string MovieName { get; set; }
public int MovieGenre { get; set; }
public string MoviePicture { get; set; }
public string MovieDescription { get; set; }
public string MovieShortText { get; set; }
public bool? MovieIs3d { get; set; }
public bool? MovieIsImax { get; set; }
public int MovieLanguage { get; set; }
public bool? MovieSubtitled { get; set; }
public int? MovieMinimalAge { get; set; }
public bool? MovieHasDrugs { get; set; }
public bool? MovieHasViolence { get; set; }
public bool? MovieHasSex { get; set; }
public bool? MovieHasSwearing { get; set; }
public bool? MovieIsScary { get; set; }
public bool? MovieHasDiscrimination { get; set; }
public string MovieTrailer { get; set; }
public int MovieLength { get; set; }
public int? Genre_GenreId { get; set; }
public int? Language_LanguageId { get; set; }
public virtual Genre Genre { get; set; }
public virtual Language Language { get; set; }
public virtual ICollection<TimeTable> TimeTables { get; set; }
}
And:
public partial class TimeTable
{
public TimeTable()
{
Reservations = new HashSet<Reservation>();
}
public int TimeTableId { get; set; }
public int MovieId { get; set; }
public int RoomId { get; set; }
public int SeatsAvaible { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public virtual Movie Movie { get; set; }
public virtual ICollection<Reservation> Reservations { get; set; }
public virtual Room Room { get; set; }
}
I want to show all the records from Movie which have one or more records in TimeTable and where StartDate.date == [given datetime].
With a simple query the movies are showing multiple times. I have tried a distinct() but that changes nothing.
Anybody here who have the solution?
Current query:
var times2 =
(from s in timetablerepo.TimeTables
orderby s.StartTime.TimeOfDay
where s.StartTime.Date == datetime.Date
select s).Distinct().ToList();
Why not start with movies first and filter by timetable:
var times = timetablerepo.Movies
.Where(m => m.TimeTables.Any(t => t.StartDate.Date == <yourdate>));

Calculate sum of multiple items in array in C#

I'm trying to get a sum for items I have within a class. To explain you better, I'm having cart object for which I can calculate the total sum with this method:
public decimal ComputeTotalValue()
{
return itemCollection.Sum(e => e.Item.Price*e.Quantity);
}
The item object in our case is this one:
public class CartItem
{
public RestItem Item { get; set; }
public int Quantity { get; set; }
}
Now the RestItem class has these properties:
public class RestItem
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int InStockNow { get; set; }
public int Order { get; set; }
public decimal Price { get; set; }
public bool HasImage { get; set; }
public bool HasModifiers { get; set; }
public string PLU { get; set; }
public int CategoryId { get; set; }
public byte[] ImageArray { get; set; }
public IEnumerable<ModifierOption> Modifiers { get; set; }
}
The last property, Modifiers is new property which I included today and this is the content:
public class ModifierOption
{
public string ID { get; set; }
public decimal Price { get; set; }
}
What I want to achieve is when the ComputeTotalValue is called, If there are ModifierOption fields as well, I want to calculate the sum of those fields as well and include the result in the total sum.
You can just add price of modifiers to price of your item, can't you?
public decimal ComputeTotalValue()
{
return itemCollection.Sum(e => (e.Item.Price + e.Item.Modifiers.Sum(m=>m.Price))*e.Quantity);
}
Do it like this:
public class RestItem
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int InStockNow { get; set; }
public int Order { get; set; }
public decimal Price { get; set; }
public bool HasImage { get; set; }
public bool HasModifiers { get; set; }
public string PLU { get; set; }
public int CategoryId { get; set; }
public byte[] ImageArray { get; set; }
public IEnumerable<ModifierOption> Modifiers { get; set; }
public decimal ComputeTotalPrice() {
return (this.Modifiers?.Sum(x => x.Price) ?? 0) + Price;
}
}
public decimal ComputeTotalPrice(){
return itemCollection?.Sum(x => x.ComputeTotalPrice()) ?? 0;
}

Categories

Resources