LINQ: Rewrite an inline query into Linq method style? - c#

How could this be re-written using LINQ methods instead of inline query style?
var cp = from DataRow r in rptDataPkg.Datasets.Item(0).Result.Rows
where (r.Field<string>("UnitItem") == "PC") &&
(r.Field<string>("UnitItem") == "Hs") &&
(r.Field<string>("UnitItem") == "U")
select new CurrProjected
{
doAddUp = (r.Field<Decimal>("Fld1") + r.Field<Decimal>("Fld2"))
== r.Field<Decimal>("Fld3")
};

I prefer this syntax to the other solutions, personally.
var cp = rptDataPkg.Datasets.Item(0).Result.Rows
.Where(r => r.Field("UnitItem") == "PC")
.Where(r => r.Field("UnitItem") == "Hs")
.Where(r => r.Field("UnitItem") == "U")
.Select(r => new CurrProjected
{
doAddUp = (r.Field("Fld1") + r.Field("Fld2"))
== r.Field("Fld3")
});

Try the following
var cp = rptDataPkg.Datasets.Item(0).Result.Rows
.Cast<DataRow>()
.Where(r => (r.Field<string>("UnitItem") == "PC") &&
(r.Field<string>("UnitItem") == "Hs") &&
(r.Field<string>("UnitItem") == "U"))
.Select(r => new CurrProjected
{
doAddUp = (r.Field<Decimal>("Fld1") + r.Field<Decimal>("Fld2"))
== r.Field<Decimal>("Fld3")
});

Related

How to use Exist sql function in Linq

var _query = _dbContext.CashVoucherDetails
.Where(x => x.CreationDate.Date >= From.Date && x.CreationDate.Date <= To.Date && (x.Type == Common.TransactionType.CPV || x.Type == Common.TransactionType.BPV) && x.CompanyCode == BranchCode && x.DebitAmount > 0)
.GroupBy(v => new { v.AccountCode})
.Select(g => new
{
AccountCode = g.Key.AccountCode,
});
var balances = _dbContext.CashVoucherDetails
.Where(x => x.CreationDate.Date <= To.Date && x.CompanyCode == BranchCode)
//.Exist(_query.Account) (I want only account which exist in upper query)
.GroupBy(v => new { v.AccountCode})
.Select(g => new
{
AccountCode = g.Key.AccountCode,
Balance = g.Sum(x => x.DebitAmount - x.CreditAmount),
});
I want to use something like EXIST here in first query I have some specific accounts and in 2nd query I want to calculate balances of those accounts.
Can you please tell how I can use Exist function in LINQ.
Thank you.
I want this query to be implemented in LINQ:
SELECT `c`.`AccountCode`, `c`.`CompanyCode` AS `LocationCode`, COALESCE(SUM(`c`.`DebitAmount` - `c`.`CreditAmount`), 0) AS `Balance`
FROM `CashVoucherDetails` AS `c`
WHERE (CONVERT(`c`.`CreationDate`, date) <= '2022-12-20') AND (`c`.`CompanyCode` = '002') and `c`.`AccountCode` IN
(
SELECT `c`.`AccountCode`
FROM `CashVoucherDetails` AS `c`
WHERE ((((CONVERT(`c`.`CreationDate`, date) >= '2022-12-20') AND (CONVERT(`c`.`CreationDate`, date) <= '2022-12-20')) AND `c`.`Type` IN ('CPV', 'BPV')) AND (`c`.`CompanyCode` = '002')) AND (`c`.`DebitAmount` > 0)
GROUP BY `c`.`AccountCode`
)
GROUP BY `c`.`AccountCode`, `c`.`CompanyCode`;
you can use Contains or Any.
_dbContext.CashVoucherDetails
.Where(x => x.CreationDate.Date <= To.Date && x.CompanyCode == BranchCode)
.Where(x => _query.Select(q => q.AccountCode).Contains(x.AccountCode))
Or
.Where(x => _query.Any(q => q.AccountCode == x.AccountCode))
Maybe something like that
var balances = _dbContext.CashVoucherDetails
.Where(x => x.CreationDate.Date <= To.Date && x.CompanyCode == BranchCode && _query.Any(q => q.AccountCode == x.AccountCode))
.GroupBy(v => new { v.AccountCode})
.Select(g => new
{
AccountCode = g.Key.AccountCode,
Balance = g.Sum(x => x.DebitAmount - x.CreditAmount),
});

optimize query with lambra expression in entity framework

I have the following query, often have excution timeout errors, have any ideas for optimization.
Thank you!
queryResult = db.Products
.Where(x => !x.product_is_deleted)
.Where(x => x.product_name.Contains(keyword) || x.product_barcode.Contains(keyword) || x.ProductType.pro_type_name.Contains(keyword) || x.ProductType.pro_type_name.Contains(keyword))
.Select(x => new ProductView
{
product_id = x.product_id,
product_barcode = x.product_barcode,
product_name = x.product_name,
product_unit = x.product_unit,
product_size = x.product_size,
product_weight = x.product_weight,
product_type_id = x.product_type_id,
product_inventory = shelf == 0 ? (x.ImportProductDetails.Where(y => y.imp_pro_detail_product_id == x.product_id && y.ImportProduct.import_pro_warehouse_id == warehouse_id ).Select(y => y.imp_pro_detail_inventory).DefaultIfEmpty(0).Sum()) : (x.ImportProductDetails.Where(y => y.imp_pro_detail_product_id == x.product_id && y.ImportProduct.import_pro_warehouse_id == warehouse_id && y.imp_pro_detail_shelf_id == shelf).Select(y => y.imp_pro_detail_inventory).DefaultIfEmpty(0).Sum()),
product_opening_stock = x.product_opening_stock,
product_type_name = x.ProductType.pro_type_name,
product_price = x.ProductPrices.Where(y => !y.proprice_is_deleted).Where(y => y.proprice_applied_datetime <= DateTime.Now).OrderByDescending(y => y.proprice_applied_datetime).Select(y => y.proprice_price).FirstOrDefault(),
product_discount_type = x.ProductDiscounts.Where(y => !y.pro_discount_is_deleted && y.pro_discount_start_datetime <= datetimeNow && y.pro_discount_end_datetime >= datetimeNow).OrderByDescending(y => y.pro_discount_id).Select(y => y.pro_discount_type).FirstOrDefault(),
product_discount_value = x.ProductDiscounts.Where(y => !y.pro_discount_is_deleted && y.pro_discount_start_datetime <= datetimeNow && y.pro_discount_end_datetime >= datetimeNow).OrderByDescending(y => y.pro_discount_id).Select(y => y.pro_discount_value).FirstOrDefault()
//product_norm_name = x.ProductionNorms.Where(y => y.pro_norm_name == x.product_id && y.pro_norm_is_applied == true).Select(y => y.pro_norm_id).FirstOrDefault()
});

Is there a way to set this entity/linq query to IEnumerable?

I'm trying to return an IEnumerable activities instead of "var"
var activities = ctx.Activities.Where(a => a.SiteID == propID)
.Where(a => a.ActivityTypeName == "Call")
.Select(x => new
{
x.DateTimeEntry,
x.Contact.OwnerContact.ParcelDatas
.FirstOrDefault(a => a.OwnerContactID == x.Contact.OwnerContact.OOwnerID)
.Parcel_LetterTracking.LMailDate,
x.FAQs.FirstOrDefault(a => a.ActivityID == x.ActivityID)
.FAQ_Library.FaqNum,
x.FAQs.FirstOrDefault(a => a.ActivityID == x.ActivityID)
.FAQ_Library.Question
});
edit: data type Object compiles but I'm not sure if that's right.
.Select already returns a an IEnumerable<TResult> also combine your ..where() clauses with && instead. https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.select?view=netframework-4.8 also one other thing you can do is use .AsEnuemerable()
var activities = ctx.Activities.Where(a => a.SiteID == propID && a.ActivityTypeName == "Call")
.Select(x => new
{
x.DateTimeEntry,
x.Contact.OwnerContact.ParcelDatas.FirstOrDefault(a => a.OwnerContactID == x.Contact.OwnerContact.OOwnerID).Parcel_LetterTracking.LMailDate,
x.FAQs.FirstOrDefault(a => a.ActivityID == x.ActivityID).FAQ_Library.FaqNum,
x.FAQs.FirstOrDefault(a => a.ActivityID == x.ActivityID).FAQ_Library.Question
}).AsEnumerable();

Summing a decimal field using Linq to datatable

I was able to get this to work after much frustration, but I was hoping someone could explain to me why this works:
var monthCharges = WRVUData.AsEnumerable()
.Where(dr => dr.Field<DateTime>("Posting_Month") == new DateTime(month.Year, i, 1))
.Where(dr => dr.Field<string>("Report_Producer_Name") == provider || dr.Field<string>("Group_Name") == group)
.Where(dr => dr.Field<decimal?>("Charges") != null)
.Sum(dr => dr.Field<decimal>("Charges"));
but this doesn't:
var monthCharges = (from r in WRVUData.AsDataView()
select new
{
charges = r.Field<decimal?>("Charges"),
activityType = r.Field<string>("Activity_Type"),
postingMonth = r.Field<DateTime>("Posting_Month"),
provider = r.Field<string>("Report_Producer_Name"),
groupName = r.Field<string>("Group_Name"),
WRVUs = r.Field<decimal>("W_RVUs")
})
.Where(dr => dr.postingMonth == new DateTime(month.Year, i, 1))
.Where(dr => dr.provider == provider || dr.groupName == group)
.Where(dr => dr.charges != null)
.Sum(dr => dr.charges);
The second version throws a "Specified cast is not valid" error. Aren't the two basically the same thing?

Mixing two linq statement into one?

I have 2 linq statements, both of them are fully working. I am wondering if it is possible to mix them into one and get proper list after one linq.
var result = list3.Where(Srodek => list4.Any(x => x == Srodek.Srodek.category1) &&
(Srodek.Srodek.Source.Device == _text || Srodek.Srodek.ID.Device == _text))
.ToList();
var list666 = list3.Select(obj => new { obj, dt = DateTime.ParseExact(obj.LeftColumn, dateFormat, CultureInfo.InvariantCulture) })
.Where(x => x.dt >= czas11 && x.dt <= czas22)
.Select(x => x.obj).ToList();
LINQ methods return IEnumerable<T>, and can operate on IEnumerable<T>.
You can write
sequence.Where(...).Select(...)
One list:
var result = list3.Where(obj => {
var dt = DateTime.ParseExact(obj.LeftColumn, dateFormat, CultureInfo.InvariantCulture);
return (list4.Any(x => x == obj.Srodek.category1) &&
(obj.Srodek.Source.Device == _text || obj.Srodek.ID.Device == _text)) ||
(dt >= czas11 && dt <= czas22);})
.ToList();
Why you cant just mix them? list.where(.........).select(.......).toList();
var result = list3.Where(Srodek => list4.Any(x => x == Srodek.Srodek.category1) &&
(Srodek.Srodek.Source.Device == _text || Srodek.Srodek.ID.Device== _text))
.Select(obj => new { obj, dt = DateTime.ParseExact(obj.LeftColumn, dateFormat, CultureInfo.InvariantCulture) })
.Where(x => x.dt >= czas11 && x.dt <= czas22)
.Select(x => x.obj)
.ToList();
You can join both linq queries using Union.
list3.Where(Srodek => list4.Any(x => x == Srodek.Srodek.category1) &&
(Srodek.Srodek.Source.Device == _text || Srodek.Srodek.ID.Device == _text))
.Union(list3.Select(obj => new { obj, dt = DateTime.ParseExact(obj.LeftColumn, dateFormat, CultureInfo.InvariantCulture) })
.Where(x => x.dt >= czas11 && x.dt <= czas22)
.Select(x => x.obj));

Categories