I have a Silverlight application and a gridview bound from a domaindatasource control, and i am querying a view from domain data source using two parameters, but from the result, i need to sum 4 columns, grouping by the others.
My metadata class:
internal sealed class vwAplicacoesMetadata
{
// Metadata classes are not meant to be instantiated.
private vwAplicacoesMetadata()
{
}
public Nullable<int> CodInternoCliente { get; set; }
public Nullable<int> CodTipoOper { get; set; }
public string CPFCNPJCliente { get { return this.CPFCNPJCliente; } set { String.Format("{0,-14}", value); } }
public string TipoClientePFPJ { get; set; }
public string NomeCliente { get; set; }
public DateTime DataOper { get; set; }
public decimal LCQtde { get; set; }
public decimal LCValor { get; set; }
public decimal LDQtde { get; set; }
public decimal LDValor { get; set; }
}
}
And the IQueryable function i need to use the groupby and sum expressions:
public IQueryable<vwAplicacoes> GetVwAplicacoesPorData(DateTime pstrDataInicio, DateTime pstrDataFinal)
{
return this.ObjectContext.vwAplicacoes.Where(d => d.DataOper > pstrDataInicio && d.DataOper < pstrDataFinal)
}
Its working, and now i need to group by CPFCNPJCliente, NomeCliente, TipoClientePFPJ, CodInternoCliente and CodTipoOper, and sum the fields LCValor, LCQtde, LDValor, LDQtde.
Any suggestion?
Try this:
return this.ObjectContext.vwAplicacoes
.Where(d => d.DataOper > pstrDataInicio && d.DataOper < pstrDataFinal)
.GroupBy(x => new {x.CPFCNPJCliente,x.NomeCliente,x.TipoClientePFPJ,x.CodInternoCliente,x.CodTipoOper})
.Select(k => new {key = k.Key,
totalLCValor = k.Sum(x=>x.LCValor),
totalLCQtde = k.Sum(x=>x.LCQtde),
totalLDValor = k.Sum(x=>x.LDValor),
totalLDQtde = k.Sum(x=>x.LDQtde)})
Related
i have following entities..
public class Paper
{
public int Id { get; set; }
public string PaperCode { get; set; }
...
}
public class MCQPaper : Paper
{
public ICollection<MCQQuestion> Questions { get; set; }
}
public class MCQQuestion : Question
{
public int MCQPaperId { get; set; }
public MCQPaper MCQPaper { get; set; }
public int? MCQOptionId { get; set; }
[ForeignKey("MCQOptionId")]
public MCQOption TrueAnswer { get; set; }
public ICollection<MCQOption> MCQOptions { get; set; }
}
public class MCQOption
{
public int Id { get; set; }
public string OptionText { get; set; }
}
and i am trying to fetch MCQPaper based on unique papercode but it always gives me empty collection of Questions
here is my Query inside Repository..
public MCQPaper GetByPaperCode(string paperCode)
{
var ans = AppDbContext.MCQPapers
.Where(paper => paper.PaperCode.Equals(paperCode))
//.Include(paper => paper.Questions)
// .ThenInclude(que => que.MCQOptions)
.Include(paper => paper.Questions)
.ThenInclude(que => que.MCQPaper)
//.Include(paper => paper.Questions)
// .ThenInclude(que => que.TrueAnswer)
.FirstOrDefault();
return ans;
}
here i have tried various combinations of include() and theninclude() but none of them work for me
and lastly ignore grammer mistakes if any
thankyou in advance
after going threw comments and searching on google i have found solution
using two queries this problem can be solved because here i have circular dependency between MCQQuestion and MCQOption
so solution is ....
public MCQPaper GetByPaperCode(string paperCode)
{
using var transaction = AppDbContext.Database.BeginTransaction();
MCQPaper ans = new MCQPaper();
try
{
ans = AppDbContext.MCQPapers
.FirstOrDefault(paper => paper.PaperCode.Equals(paperCode));
var questions = AppDbContext.MCQQuestions
.Include(que => que.MCQOptions)
.Where(que => que.MCQPaperId == ans.Id);
ans.Questions = questions.ToList();
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
}
return ans;
}
I want to Find Username by userId
this code snippet working
Discussion_CreateBy = db.AspNetUsers.Find(discussion.CreatedBy).UserName,
and this once not working in following controller class
Comment_CreateBy = db.AspNetUsers.Find(c.CreatedBy).UserName,
this is my model classes
public class DiscussionVM
{
public int Disussion_ID { get; set; }
public string Discussion_Title { get; set; }
public string Discussion_Description { get; set; }
public Nullable<System.DateTime> Discussion_CreateDate { get; set; }
public string Discussion_CreateBy { get; set; }
public string Comment_User { get; set; }
public IEnumerable<CommentVM> Comments { get; set; }
}
public class CommentVM
{
public int Comment_ID { get; set; }
public Nullable<System.DateTime> Comment_CreateDate { get; set; }
public string Comment_CreateBy { get; set; }
public string Comment_Description { get; set; }
}
this is whole controller class
public ActionResult Discussion_Preview()
{
int Discussion_ID = 1;
var discussion = db.AB_Discussion.Where(d => d.Discussion_ID == Discussion_ID).FirstOrDefault();
var comments = db.AB_DiscussionComments.Where(c => c.Discussion_ID == Discussion_ID);
DiscussionVM model = new DiscussionVM()
{
Disussion_ID = discussion.Discussion_ID,
Discussion_Title = discussion.Discussion_Name,
Discussion_Description = discussion.Discussion_Name,
Discussion_CreateBy = db.AspNetUsers.Find(discussion.CreatedBy).UserName,
Discussion_CreateDate = discussion.CreatedDate,
Comments = comments.Select(c => new CommentVM()
{
Comment_ID = c.Comment_ID,
Comment_Description = c.Comment_Discription,
Comment_CreateBy = db.AspNetUsers.Find(c.CreatedBy).UserName,
Comment_CreateDate = c.CreatedDate
})
};
return View(model);
}
Getting following error
Method 'Project.Models.AspNetUser Find(System.Object[])' declared on type 'System.Data.Entity.DbSet1[Project.Models.AspNetUser]' cannot be called with instance of type 'System.Data.Entity.Core.Objects.ObjectQuery1[Project.Models.AspNetUser]'
Discussion_CreateBy = db.AspNetUsers.Find(discussion.CreatedBy).UserName
Works because discussion is an in-memory object because you are executing a query by calling FirstOrDefault on it:
var discussion = db.AB_Discussion.Where(d => d.Discussion_ID == Discussion_ID).FirstOrDefault();
On the other hand in the following statement:
db.AspNetUsers.Find(c.CreatedBy).UserName
c is not queried yet because
db.AB_DiscussionComments.Where(c => c.Discussion_ID == Discussion_ID)
returns an IQueriable and not the actual collection of comments
The easiest way to fix it is to bring all your comments into memory (since you are anyway need them all) :
var comments = db.AB_DiscussionComments.Where(c => c.Discussion_ID == Discussion_ID).ToList();
I have two models:
public class CarRent
{
public string CarName { get; set; }
public string SystemId { get; set; }
public DateTime RentEndDate { get; set; }
}
public class CarPurchase
{
public string CarName { get; set; }
public string SystemId { get; set; }
public decimal Mileage { get; set; }
}
I need to combine them into one list, group by CarName and then inside each group I need to sort models initially by SystemId, but then if models have the same SystemId - I need to sort CarRent models by RentEndDate and CarPurchase by Mileage.
What I have tried:
I defined an interface:
public interface ICarPurchaseOrdered
{
string CarName { get; }
string SystemId { get; }
string Order { get; }
}
and got my models to implement it, the Order property just returns string representation of second order criteria, then I defined a view model:
public class GroupedCardList
{
public string CarName { get; set; }
public IEnumerable<ICarPurchaseOrdered> Cars { get; set; }
}
then I have a grouper that just groups my models:
public class CarGrouper
{
IEnumerable<GroupedCardList> Group(IEnumerable<ICarPurchaseOrdered> cars)
{
return cars.GroupBy(c => c.CarName)
.OrderBy(c => c.Key)
.Select(c => new GroupedCardList()
{
CarName = c.Key,
Cars = c.OrderBy(n => n.SystemId)
.ThenBy(n => n.Order)
});
}
}
But it doesn't work right because it sorts strings and I get the car purchase with Milage=1200 before the car with Milage=90.
I know that example is a little bit contrived but it perfectly represents the issue that I have right now. Please give me some advice.
One way to do it would be to implement a custom IComparer. If you extract a common base class:
public class Car
{
public string CarName { get; set; }
public string SystemId { get; set; }
}
public class CarRent : Car
{
public DateTime RentEndDate { get; set; }
}
public class CarPurchase : Car
{
public decimal Mileage { get; set; }
}
Then a IComparer<Car> implementation might look like this:
public class CarComparer : IComparer<Car>
{
public int Compare(Car x, Car y)
{
// compare by system id first
var order = string.Compare(x.SystemId, y.SystemId);
if (order != 0)
return order;
// try to cast both items as CarRent
var xRent = x as CarRent;
var yRent = y as CarRent;
if (xRent != null && yRent != null)
return DateTime.Compare(xRent.RentEndDate, yRent.RentEndDate);
// try to cast both items as CarPurchase
var xPurc = x as CarPurchase;
var yPurc = y as CarPurchase;
if (xPurc != null && yPurc != null)
return decimal.Compare(xPurc.Mileage, yPurc.Mileage);
// now, this is awkward
return 0;
}
}
You can then pass the comparer instance to List.Sort and Enumerable.OrderBy.
You can use int.Parse and order integers instead of strings
c.OrderBy(n => n.SystemId)
.ThenBy(n => int.Parse(n.Order))
The ICarPurchaseOrdered.Order used to order (then) by is a string type; Hence why the ordering is done alphabetically.
I would suggest to change the type of ICarPurchaseOrdered.Order to object,
so the Orderbycan use the underlying object (eitherDateTimeorDecimal`) to order.
**Update:
Try this
c.OrderBy(n => n.SystemId)
.ThenBy(n => n.GetType())
.ThenBy(n => n.Order);
I receive this parameter from my request:
sort=homeCountry
I need to sort by whatever column is sent to the sort parameter, so I created a method like so:
string sort = "homeCountry";
Func<PaymentRateTrip, string> orderBy = (
x => sort == "homeCountry" ? x.HomeCountry :
sort == "hostCountry" ? x.HostCountry :
sort == "homeLocation" ? x.HomeLocation :
sort == "hostLocation" ? x.HostLocation :
x.HomeLocation
);
This works correctly.
However, the columns above are all strings. But, I also need to add decimal columns like so:
string sort = "homeCountry";
Func<PaymentRateTrip, string> orderBy = (
x => sort == "homeCountry" ? x.HomeCountry :
sort == "hostCountry" ? x.HostCountry :
sort == "homeLocation" ? x.HomeLocation :
sort == "hostLocation" ? x.HostLocation :
sort == "oneWayRate" ? x.oneWayRate :
x.HomeLocation
);
It gives me an error on the x.HostLocation that says:
Type of conditional expression cannot be determined because there is
no implicit conversion between 'string' and 'decimal?'
Is there a better way to do what I am trying to do? I am looking for:
A way that will work.
A way that is readable (something like a switch case).
Edit: PaymentRateTrip.cs
public class PaymentRateTrip
{
public Guid? Id { get; set; }
public Guid HomeCountryId { get; set; }
public string HomeCountry { get; set; }
public Guid HomeLocationId { get; set; }
public string HomeLocation { get; set; }
public Guid? HostCountryId { get; set; }
public string HostCountry { get; set; }
public Guid? HostLocationId { get; set; }
public string HostLocation { get; set; }
public decimal? OneWayRate { get; set; }
public decimal? RoundTripRate { get; set; }
public Guid? OneWayCurrencyId { get; set; }
public Guid? RoundTripCurrencyId { get; set; }
}
I'd just make an extension method:
public static IEnumerable<PaymentRateTrip> Sort(this IEnumerable<PaymentRateTrip> list, string sort)
{
switch (sort)
{
case "homeCountry":
return list.OrderBy(x => x.Whatever);
case "somethingElse":
return list.OrderBy(x => x.Whatever);
//....
}
}
It might seem to simple but just do this
var prop = typeof(PaymentRateTrip).GetProperty(sort);
var ordered = lst.OrderBy(p => prop.GetValue(p));
this works as long as the sort name is part of the object.
In your case the function is (p => prop.GetValue(p))
I have the following class:
public class EntityJESummary
{
public int JEGroupingId { get; set; }
public int PartnershipId { get; set; }
public int JEId { get; set; }
public DateTime BookingDate { get; set; }
public DateTime EffectiveDate { get; set; }
public bool Allocated { get; set; }
public int JEEstate { get; set; }
public float Debit { get; set; }
public float Credit { get; set; }
public string JEComments { get; set; }
public EntityJESummary()
{
}
}
And here I'm using Linq to filter out DataRows from a source. I'm trying to fit information from this datasource into this new holder type class.
Any suggestions?
_dttMasterViewTransaction = dtsTransaction.Tables["tblTransaction"];
var datos = _dttMasterViewTransaction.AsEnumerable()
.Where(r => r["JEID"] == FundsID)
.Select(new EntityJESummary ???
Notice where I'm using r["foo"], I'm fetching data from each DataRow. I need to get specific rows and fit them into specific properties of my holder class.
Also, in the data table, there might be many rows for a single JEId, so I'd like to grab each Debit from each datarow and Sum it into the float Debit property.
Any suggestions would be very much appreciated. :)
Untested but try something similar to what you did with the Where clause:
var datos = _dttMasterViewTransaction.AsEnumerable()
.Where(r => r["JEID"] == FundsID)
.Select(r => new EntityJESummary {
JEGroupingId = r["JEGroupingId"],
PartnershipId = r["PartnershipId"],
.....
} );
You can make use of Object Initalizers.
_dttMasterViewTransaction = dtsTransaction.Tables["tblTransaction"];
var datos = _dttMasterViewTransaction.AsEnumerable()
.Where(r => r["JEID"] == FundsID).Select(r =>
new EntityJESummary() {
JEGroupingId = r["JEID"],
PartnershipId = r["PartnershipId"]
};