Can I put this in separate class? - c#

I have this repetitive piece of code:
var expCodes = (from cpdet in _dataContextOrders.CodeProfileDetails
join cpd in _dataContextOrders.CodeProfileDefinitions on cpdet.CodeProfileDefinitionID equals cpd.ID
join cp in _dataContextOrders.CodeProfiles on cpd.CodeProfileID equals cp.ID
join cc in _dataContextOrders.FMSCostCentres on cpdet.CostCentreID equals cc.ID
join ec in _dataContextOrders.FMSExpenseCodes on cpdet.ExpenseCodeID equals ec.ID
where cp.ID == Convert.ToInt32(intCostCodeProfileId)
&& cpdet.CostCentreID == Convert.ToInt32(intCostCentreSelected)
&& ec.Active == true
select new
{
ec.ID,
ec.CostCentreID,
ExpenseCodeExternalRef = ec.ExternalRef,
ExpenseCodeDescription = ec.Description,
displayExpenseCode = ec.ExternalRef + " " + ec.Description
}).Distinct().OrderBy(ec => ec.displayExpenseCode);
ddlExpCode1.DataSource = expCodes;
ddlExpCode1.DataTextField = "displayExpenseCode";
ddlExpCode1.DataValueField = "ID";
What I would like to do is to put it into a Class on its own, as we did before LinqToSql, that I can call from my aspx.cs page, using the 2 parameters, intCostCodeProfileId and intCostCodeProfileId and it will return the data for the Drop Down List.
How can I do this?

You have to create a model class that matches the properties in your select statement (ID, CostCentreId etc.). Then modify the select new { to select new FreshlyCreatedModelClass() {.
The only way to return an anonymous type from your method is to use either IEnumerable<object> or IEnumerable<dynamic> neither which should be recommended in this scenario. Your method should return IEnumerable<FreshlyCreatedModelClass> (or IQueryable<FreshlyCreatedModelClass> could be used if you need to build the query further).
After you have sorted the model class, you can simply move the code to a separate method.

Create a normal class (e.g. Connection.cs) and add some code like this:
public class MyDataSourceReturner
{
public static Object retDatasource(Object _dataContextOrders, int intCostCodeProfileId){
var expCodes = (from cpdet in _dataContextOrders.CodeProfileDetails
join cpd in _dataContextOrders.CodeProfileDefinitions on cpdet.CodeProfileDefinitionID equals cpd.ID
join cp in _dataContextOrders.CodeProfiles on cpd.CodeProfileID equals cp.ID
join cc in _dataContextOrders.FMSCostCentres on cpdet.CostCentreID equals cc.ID
join ec in _dataContextOrders.FMSExpenseCodes on cpdet.ExpenseCodeID equals ec.ID
where cp.ID == Convert.ToInt32(intCostCodeProfileId)
&& cpdet.CostCentreID == Convert.ToInt32(intCostCentreSelected)
&& ec.Active == true
select new
{
ec.ID,
ec.CostCentreID,
ExpenseCodeExternalRef = ec.ExternalRef,
ExpenseCodeDescription = ec.Description,
displayExpenseCode = ec.ExternalRef + " " + ec.Description
}).Distinct().OrderBy(ec => ec.displayExpenseCode);
return expCodes;
}
}
Afterwards you can use this code like this:
ddlExpCode1.DataSource = MyDataSourceReturner.retDatasource(_dataContextOrders, 5);
and receive your DataSource.

Related

AND between multiple form clauses

I have this viewModel
var viewModel = from c in _context.Companies
join co in _context.Component on c.id equals co.company_id
select new Joincco { Companies = c, Component = co} ;
and another model:
from check in _context.Companies
where
check.company_type.Contains(checkedBoxes[.....]) ||
check.company_type.Contains(....) ||
check.company_type.Contains(....)
select new Joincco { Companies = check }
I need a new view that can provide AND between them.
I need to get company_types from Companies that contains specific values and some properties equals a specific value from component.How can I do that?
Used intersect
return View(deneme.Intersect(longlinq).OrderBy(m => m.Companies.company_name));

Why LINQ Sum() throws "System.Collections.Generic.KeyNotFoundException"?

Here I have
System.Collections.Generic.KeyNotFoundException: 'The given key 'EmptyProjectionMember' was not present in the dictionary.'
var res = (from c in _context.Check
join cp in _context.CheckProduct on c.Id equals cp.CheckId
join p in _context.Product on cp.ProductId equals p.Id
where c.Date.Date == date.Date
select (cp.Quantity * Decimal.ToDouble(p.Price))).Sum();
But when I write this, the code is working:
var res = (from c in _context.Check
join cp in _context.CheckProduct on c.Id equals cp.CheckId
join p in _context.Product on cp.ProductId equals p.Id
where c.Date.Date == date.Date
select (cp.Quantity * Decimal.ToDouble(p.Price)));
double sum = 0;
foreach(var el in res)
{
sum += el;
}
Why Sum() is not working?
Try the following:
res = (from c in _context.Check
join cp in _context.CheckProduct on c.Id equals cp.CheckId
join p in _context.Product on cp.ProductId equals p.Id
where c.Date.Date == date.Date
select (cp.Quantity * Decimal.ToDouble(p.Price)))
.DefaultIfEmpty(0)
.Sum();
Looks like there is nothing to select, so in that case, default to 0.
In the second case, you try to iterate an empty enumerable so it won't even go into the for each clause.
I was getting the same error when calling Any with an unsatisfied filter
public static bool IsBooking(this Address address)
=> address.ReferenceTypes.Any(referenceType
=> referenceType == ReferenceType.Booking
&& address.IsActive);
After first making sure that some elements exist, it is working - but it doesn't really make sense as now I'm calling Any twice
public static bool IsBooking(this Address address)
=> address.ReferenceTypes.Any()
&& address.ReferenceTypes.Any(referenceType
=> referenceType == ReferenceType.Booking
&& address.IsActive);
You need to call .ToList() before .Sum().

Include("myTable") in Linq to Entities in Silverlight

I need help, I have a method to Access to my Orders table:
public IQueryable<Orders> GetOrders()
{
return this.ObjectContext.Orders.Include("UnitDetail");
}
it Works very well, and I can see it from the window Data Source, and can see Orders and UnitDetail from here
But I need make some considerations for the selected rows, so I made the next method:
public IQueryable<Orders> GetOpenOrders(string _iduni)
{
ObjectSet<Orders> orders = this.ObjectContext.Orders;
ObjectSet<Estatus> estatus = this.ObjectContext.Estatus;
ObjectSet<DetailUnit> units = this.ObjectContext.DetailsUnit;
ObjectSet<ServiceType> servicetype = this.ObjectContext.ServiceType;
var query =
(from o in orders
join e in estatus on o.ID equals e.IDOrder
join u in units on o.IDUni equals u.IDUni
join t in servicetype on u.IDType equals t.IDType
where o.IDUni.Equals(_iduni)
&& !estatus.Any(oe => (oe.Estatus == "CANCELADA" || oe.Estatus == "CERRADA")
&& oe.IDOrder == o.ID)
select o).Distinct();
return query.AsQueryable();
}
This show me the correct recs, but what happend? why I don't see UnitDetail, when I inspect the result UnitDetail is null, how I can do for put the Include clausule in this new method??
Thanks a lot in advance
Because you haven't put the Include in your new method anywhere.
EDITED: to remove the unused joins.
You should be able to just use Include as you did in your GetOrders method, and so have it as a part of your existing orders variable. You are not actually using those joins anywhere, are you intending to?
Like this:
public IQueryable<Orders> GetOpenOrders(string _iduni)
{
var query =
(from o in this.ObjectContext.Orders.Include("UnitDetail")
where o.IDUni.Equals(_iduni)
&& !this.ObjectContext.Estatus.Any(oe => (oe.Estatus == "CANCELADA" || oe.Estatus == "CERRADA")
&& oe.IDOrder == o.ID)
select o).Distinct();
return query.AsQueryable();
}

Linq updating different table after join process

I have combined 3 of my tables by using linq join. After that i want to update this table by using data that i get from webform. How can i do this ? My implementation is below
public void updateShoes(Shoe shoe)
{
var query = from b in db.BrandTbls.AsQueryable()
join m in db.ShoeModelTbls on b.BrandID equals m.BrandID
join s in db.ShoeTbls on m.ModelID equals s.ModelID
where shoe.ShoeID == s.ShoeID
orderby m.ModelName
select new
{
s.ShoeID,
s.Size,
s.PrimaryColor,
s.SecondaryColor,
s.Quantity,
m.ModelName,
m.Price,
b.BrandName
};
}
Though your approach is a little bit unclear right now (for e.g. we don't know which entities you are trying to update), however you can modify your code like this,
public void updateShoes(Shoe shoe)
{
var query = from b in db.BrandTbls.AsQueryable()
join m in db.ShoeModelTbls on b.BrandID equals m.BrandID
join s in db.ShoeTbls on m.ModelID equals s.ModelID
where shoe.ShoeID == s.ShoeID
orderby m.ModelName
select new
{
Shoe = shoe, Brand = b, Model = m
};
foreach(var o in query)
{
o.Shoe.ColorName = "Black";
o.Brand.BrandName = "New Branding";
o.Model.ModelName = "Something else";
}
db.SaveChanges();
}
Rather picking selected properties from each Entity, you can pick whole entity. Then you can update each entity in a loop as I have doing above.
I like the all-in-one linq update. Especially if I need to join on an existing object list.
var UpdQuery = (from b in db.BrandTbls
join m in db.ShoeModelTbls on b.BrandID equals m.BrandID
join s in db.ShoeTbls on m.ModelID equals s.ModelID
where shoe.ShoeID == s.ShoeID
orderby m.ModelName
select new { b, m, s }
// now for the update portion of the query
).Select(result =>
{
result.s.ShoeID = shoe.ID;
result.s.Size = shoe.Size;
result.s.PrimaryColor = shoe.PrimaryColor;
result.s.SecondaryColor = shoe.SecondaryColor;
result.s.Quantity = shoe.Quantity;
result.m.ModelName = shoe.ModelName;
result.m.Price = shoe.Price;
result.b.BrandName = shoe.BrandName;
return result; // this is important
}).ToList(); // tolist actually runs the query to update the objects
db.SaveChanges(); // write changes back to DB
To update an entity you will need to retrieve the entity from the context, modify the values, then call SaveChanges() to do the update.
foreach( var n in query)
{
var shoe = db.Shoes.Find(n.ShoeID);
shoe.Size = webFormData.Size;
}
db.SaveChanges();

How to Create the Left Join by using the group by data

I have three Table One is "Allowance " ,"Balance" and "TimeoffRequests" in these three table common columns are EmployeeId and TimeoffTypeId, Now i need to get the requested hours of one leave type by grouping thier timeoffTypeId and EmployeeId from the table "TimeoffRequests" , and got the "TimeOffHours". for the i wrote the code like
var query = (from tr in TimeOffRequests
where tr.EmployeeID == 9
group tr by new { tr.EmployeeID, tr.TimeOffTypeID } into res
select new
{
EmployeeID = res.Key.EmployeeID,
TimeOffTypeID = res.Key.TimeOffTypeID,
TotalHours = res.Sum(x => x.TimeOffHours)
}).AsEnumerable();
Now I need to join these results with the first table and have to get the all the employees, and timeoffTypes from the UserAllowance and corresponding TimeoffHours from the grouped table. for getting left joined query i wrote like below.
var requestResult = (from UA in UserAllowances
join UB in UserBalances on UA.EmployeeID equals UB.EmployeeID
where UA.TimeOffTypeID == UB.TimeOffTypeID && UA.EmployeeID == 9
&& UA.TimeOffType.IsDeductableType == true // LeftJoin
join rest in query on UA.EmployeeID equals rest.EmployeeID into penidngRequst
from penReq in penidngRequst.DefaultIfEmpty()
where penReq.TimeOffTypeID == UA.TimeOffTypeID
select new EmployeeTimeOffBalanceModel
{
TimeOffTypeID = UA.TimeOffTypeID != null ? UA.TimeOffTypeID : 0,
YearlyAllowanceHrs = (UA.YearlyAllowanceHrs != null) ? UA.YearlyAllowanceHrs : 0,
BalanceHours = UB.BalanceHrs != null ? UB.BalanceHrs : 0,
PendingHours = (decimal)((penReq != null) ? (penReq.TotalHours) : 0),
EmployeeID = UA != null ? UA.EmployeeID : 0,
}).ToList().Distinct();
It is giving only timeOFfType containing in grouped data,even though I wrote leftjoin for the query using the "into" and DefaultIfEmpty() keywords. the results becomes as like:
and by using the "linqPad" editor i found that it is applying the Cross or Outer Join instead of "left join" what will be the reason.
If I remove this line of code " where penReq.TimeOffTypeID
== UA.TimeOffTypeID" this showing all the timeoffTypes with cross join with repeatation like
How can I achieve left join with tables with Grouped data and showing null values if timeofftypes didn't having the any request?
You might want to move the where clause into the the on equals clause as shown below
join rest in query on new { UA.EmployeeID, UA.TimeOffTypeID } equals new { rest.EmployeeID, rest.TimeOffTypeID } into penidngRequst
from penReq in penidngRequst.DefaultIfEmpty()
You can change
where penReq.TimeOffTypeID == UA.TimeOffTypeID
to
where penReq == null || penReq.TimeOffTypeID == UA.TimeOffTypeID

Categories

Resources