cast IEnumerable<T> To Dictionary<int,T> - c#

I have a method with this return type :
IEnumerable<T>
I want to map this Method and fill in a Dictionary.
Expected result is: Dictionary<int, T>
Dictionary<int, LeaveTypeDto> leaveType = new Dictionary<int, LeaveTypeDto>();
LeaveType.GetList(string.Empty).ToDictionary<int, LeaveTypeDto>();
How can I do this?
Note: GetList return type is IEnumerable of LeaveType, and some fields bust be map in LeaveTypeDto and some fields in LeaveType:
"ID,Title,HourlyAvailable,..."
ID is unique and must be use as key in my dictionary, and other field must be map to LeaveTypeDto.

You can specify the key, or the key and value, to take from an enumerable.
If I have a class like so:
public class MyClass
{
public int Id {get;set;}
public string Name {get;set;}
}
I can write the following to get a Dictionary<int, MyClass>:
IEnumerable<MyClass> values;
IDictionary<int, MyClass> valueDict = values.ToDictionary(t => t.Id);
or the following to get a Dictionary<int, string>:
IEnumerable<MyClass> values;
IDictionary<int, string> valueDict = values.ToDictionary(t => t.Id, t => t.Name);

I Defined an Extention Method On LeaveType :
public static DTO.LeaveTypeDto ToDto(this DataModel.Timekeeper.LeaveType leaveType)
{
return new DTO.LeaveTypeDto
{
ID = leaveType.ID,
Code = leaveType.Code,
Title = leaveType.Title,
DailyAvailable = leaveType.DailyAvailable,
HourlyAvailable = leaveType.HourlyAvailable,
ShiftBaseAvailable = leaveType.ShiftBaseAvailable,
PredefinedRemaining = leaveType.PredefinedRemaining,
Active = leaveType.Active,
StandardLeaveType = leaveType.StandardLeaveType,
NotRequestAutomaticaly = leaveType.NotRequestAutomaticaly,
TemplateFileID = leaveType.TemplateFileID,
ObligateChooseSubstituteForDailyLeave = leaveType.ObligateChooseSubstituteForDailyLeave,
ObligateChooseSubstituteForHourlyLeave = leaveType.ObligateChooseSubstituteForHourlyLeave,
ObligateChooseSubstituteForShiftBaseLeave = leaveType.ObligateChooseSubstituteForShiftBaseLeave,
ObligateChooseInsertAttachment = leaveType.ObligateChooseInsertAttachment,
CheckSubstituteLimit = leaveType.CheckSubstituteLimit,
AbsenceRespiteYearXferLimitDays = leaveType.AbsenceRespiteYearXferLimitDays,
AbsenceRespiteYearXferMode = leaveType.AbsenceRespiteYearXferMode,
AbsenceRespiteYearXferValuesSummarize = leaveType.AbsenceRespiteYearXferValuesSummarize,
DailyRequestRegisterRespite = leaveType.DailyRequestRegisterRespite,
DayMaxHourlyMinutes = leaveType.DayMaxHourlyMinutes,
DayWorkMinutes = leaveType.WorkingPeriodMaxHourlyMinutes,
DecreaseAllOnNXOverflow = leaveType.DecreaseAllOnNXOverflow,
DecreaseBasedOnMonthWorkingDays = leaveType.DecreaseBasedOnMonthWorkingDays,
DecreaseDayWorkMinutesOnExtraWorkDays = leaveType.DecreaseDayWorkMinutesOnExtraWorkDays,
DecreaseOnExtraWorkDays = leaveType.DecreaseOnExtraWorkDays,
DecreaseOnHolidays = leaveType.DecreaseOnHolidays,
HourlyInOFFDayAvailable=leaveType.HourlyInOFFDayAvailable,
YearXferValuesSummarize = leaveType.YearXferValuesSummarize,
YearXferPercentage=leaveType.YearXferPercentage,
MaxContinuousDaysLimit = leaveType.MaxContinuousDaysLimit,
HourlyRequestRegisterRespite = leaveType.HourlyRequestRegisterRespite,
YearXferMode = leaveType.YearXferMode,
MonthlyDaysLimit = leaveType.MonthlyDaysLimit,
MonthlyXMinsLimit = leaveType.MonthlyXMinsLimit,
YearXferLimitDays = leaveType.YearXferLimitDays,
YearLimitDays = leaveType.YearLimitDays,
MonthStorable = leaveType.MonthStorable,
YearHourlyMinsLimit = leaveType.YearHourlyMinsLimit,
MonthPreusable = leaveType.MonthPreusable,
MonthlyNXMinsLimit = leaveType.MonthlyNXMinsLimit,
MonthMaxHourlyMinutes = leaveType.MonthMaxHourlyMinutes,
IncreaseAbsenceRespiteRemaining = leaveType.IncreaseAbsenceRespiteRemaining,
DailyLeaveRequestCountPerMonthForOthers = leaveType.DailyLeaveRequestCountPerMonthForOthers,
DailyLeaveRequestDurationPerMonthForOthers = leaveType.DailyLeaveRequestDurationPerMonthForOthers,
ShiftLeaveRequestCountPerMonthForOthers = leaveType.ShiftLeaveRequestCountPerMonthForOthers,
ShiftLeaveRequestDurationPerMonthForOthers = leaveType.ShiftLeaveRequestDurationPerMonthForOthers,
HourlyLeaveRequestCountPerMonthForOthers = leaveType.HourlyLeaveRequestCountPerMonthForOthers,
UseLeaveRequetLimitForOthersPerMonth = leaveType.UseLeaveRequetLimitForOthersPerMonth,
DailyCountPerMonth = leaveType.DailyCountPerMonth,
CheckMeritRemainingInUnpayedRequest = leaveType.CheckMeritRemainingInUnpayedRequest,
DayMinHourlyMinutes = leaveType.DayMinHourlyMinutes,
FirstPresenceRangeHourlyCountPerMonth = leaveType.FirstPresenceRangeHourlyCountPerMonth,
FirstPresenceRangeLenght = leaveType.FirstPresenceRangeLenght,
FirstPresenceRangeMaxHourlyLimit = leaveType.FirstPresenceRangeMaxHourlyLimit,
FirstPresenceRangeMinHourlyLimit= leaveType.FirstPresenceRangeMinHourlyLimit,
HourlyCountPerMonth = leaveType.HourlyCountPerMonth,
HourlyLeaveRequestDurationPerMonthForOthers = leaveType.HourlyLeaveRequestDurationPerMonthForOthers,
IsMonthMaxHourlyStorableToCurrent = leaveType.IsMonthMaxHourlyStorableToCurrent,
LastPresenceRangeHourlyCountPerMonth = leaveType.LastPresenceRangeHourlyCountPerMonth,
LastPresenceRangeLenght = leaveType.LastPresenceRangeLenght,
LastPresenceRangeMaxHourlyLimit = leaveType.LastPresenceRangeMaxHourlyLimit,
LastPresenceRangeMinHourlyLimit = leaveType.LastPresenceRangeMinHourlyLimit,
MiddlePresenceRangeHourlyCountPerMonth = leaveType.MiddlePresenceRangeHourlyCountPerMonth,
MiddlePresenceRangeMaxHourlyLimit = leaveType.MiddlePresenceRangeMaxHourlyLimit,
MiddlePresenceRangeMinHourlyLimit = leaveType.MiddlePresenceRangeMinHourlyLimit,
MonthMaxDailyDays=leaveType.MonthMaxDailyDays,
MonthMaxHourlyStorable=leaveType.MonthMaxHourlyStorable,
ShiftBaseCountPerMonth=leaveType.ShiftBaseCountPerMonth,
SuspendsPersonnelStatus=leaveType.SuspendsPersonnelStatus,
WorkingPeriodMaxHourlyMinutes=leaveType.WorkingPeriodMaxHourlyMinutes,
YearXMonthMaxHourlyferLimitHours=leaveType.YearXMonthMaxHourlyferLimitHours,
YearXMonthMaxHourlyferMode=leaveType.YearXMonthMaxHourlyferMode
};
}
and by this Line My problem Solved.:)
GetList(string.Empty).ToDictionary(lt => lt.ID, lt => lt.ToDto())

If ID is part of LeaveTypeDto
var q = GetList(string.Empty).ToDictionary(b => b.ID);
else use the select overload to get index and then use ToDictionary()
var q = GetList(string.Empty).Select((element, index) => new { i= index, e = element }).ToDictionary(b => b.i, b => b.e);

What about System.Linq
GetList(string.Empty).ToDictionary(k => int.Parse(k.ID))
Note, the previous example is valid if ID is string, if it is int then even simpler
GetList(string.Empty).ToDictionary(k => k.ID)

Related

Filter products with ElasticSearch concat a lot of filter

I've been trying to filter products with Elasticsearch for a few hours, unfortunately to no avail.
I need to find products that belong to certain categories and at the same time have selected several brands and one size.
Help :(
json screen
querycontainer build method
private QueryContainer CreateOrQueryFromFilter(QueryContainer queryContainer, SortedSet<string> filter, string fieldName)
{
if (filter != null && filter.Count > 0)
{
foreach (var item in filter)
{
queryContainer |= new TermQuery()
{
Name = fieldName + "named_query",
Boost = 1.1,
Field = fieldName,
Value = item
};
}
}
return queryContainer;
}
and search method
public ResultModel SearchRequest(RequestModel r)
{
string key = string.Format("search-{0}-{1}", r.CacheKey + "-" + ProductCatalog.Model.Extension.StringHelper.UrlFriendly(r.SearchText), r.Prefix);
node = new Uri("http://xxxx:9200/");
settings = new ConnectionSettings(node);
settings.DisableDirectStreaming();
settings.DefaultIndex("products");
client = new ElasticClient(settings);
// return AppCache.Get(key, () =>
// {
DateTime start = DateTime.Now;
ResultModel result = new ResultModel(r.Canonical, r.RouteObject);
if (!string.IsNullOrEmpty(r.Prefix))
{
result.Prefix = r.Prefix;
}
QueryContainer c = new QueryContainer();
if (r.CategoryFilterChilds != null && r.CategoryFilterChilds.Count > 0)
{
var a1 = new SortedSet<string>(r.CategoryFilterChilds.Select(a => (string)a.ToString()));
c = CreateOrQueryFromFilter(c, a1, "categories");
}
else
{
if (r.CategoryFilterRoots != null && r.CategoryFilterRoots.Count > 0)
{
var a1 = new SortedSet<string>(r.CategoryFilterRoots.Select(a => (string)a.ToString()));
c = CreateOrQueryFromFilter(c, a1, "categories");
}
else
{
// null
}
}
var filters = new AggregationDictionary();
if (r.IsBrandFilter)
{
c = CreateOrQueryFromFilter(c, r.SelectedBrands, "brands");
}
if (r.IsColorFilter)
{
c = CreateOrQueryFromFilter(c, r.SelectedBrands, "colors");
}
int skip = (r.Page * r.PageSize) - r.PageSize;
ISearchRequest r2 = new SearchRequest("products");
r2.From = 1;
r2.Size = r.PageSize;
r2.Query = c;
string[] Fields = new[] { "brands", "shopId" };
AggregationBase aggregations = null;
foreach (string sField in Fields)
{
var termsAggregation = new TermsAggregation("agg_" + sField)
{
Field = sField,
Size = 120,
Order = new List<TermsOrder> { TermsOrder.TermDescending }
};
if (aggregations == null)
{
aggregations = termsAggregation;
}
else
{
aggregations &= termsAggregation;
}
}
r2.Aggregations = aggregations;
var c2 = client.Search<ShopProductElastic>(r2);
var ShopsBuf = (Nest.BucketAggregate)(c2.Aggregations["agg_brands"]);
var ShopsCount = ShopsBuf.Items.Count();
var results = c2;
result.BrandsRequest = new SortedDictionary<string, int>();
foreach (Nest.KeyedBucket<object> item in ShopsBuf.Items)
{
result.BrandsRequest.Add((string)item.Key, (int)(item.DocCount ?? 0));
}
result.CategorySelected = r.CategoryCurrent;
result.TotalCount = 10;
var costam = results.Documents.ToList();
var targetInstance = Mapper.Map<List<Products>>(costam);
result.Products = targetInstance;
result.Page = r.Page;
result.PageSize = r.PageSize;
result.IsBrandFilter = r.IsBrandFilter;
result.IsColorFilter = r.IsColorFilter;
result.IsPatternFilter = r.IsPatternFilter;
result.IsSeasonFilter = r.IsSeasonFilter;
result.IsShopFilter = r.IsShopFilter;
result.IsSizeFilter = r.IsSizeFilter;
result.IsStyleFilter = r.IsStyleFilter;
result.IsTextileFilter = r.IsTextileFilter;
DateTime stop = DateTime.Now;
result.SearchTime = stop - start;
result.SearchText = r.SearchText;
return result;
// }, TimeSpan.FromHours(8));
}
I have all products that have a given brand or categories. However, i need all products of a selected brand in selected categories

Remove item from a list that is not in another list with LINQ

I have two lists which are different
public Ingrédient(int p_noIngrédient, string p_nomIngrédient, bool p_périssable,
double p_prixAuKilo)
{
NoIngrédient = p_noIngrédient;
NomIngrédient = p_nomIngrédient;
Périssable = p_périssable;
PrixAuKilo = p_prixAuKilo;
}
public Recette(int p_noPlat, int p_noIngrédient, double p_quantité)
{
NoPlat = p_noPlat;
NoIngrédient = p_noIngrédient;
Quantité = p_quantité;
}
I want to find all NoIngrédientin Ingrédient that are not in Recette. Right now I have this but it doesn't work.
void RetraitIngrédient(List<Recette> p_recettes,ref List<Ingrédient> p_ingrédients)
{
foreach (Recette recettes in p_recettes)
{
Ingrédient ingrédients =
p_ingrédients.Find(i => i.NoIngrédient != recettes.NoIngrédient);
WriteLine("{0,6} : {1:6}",ingrédients.NoIngrédient, ingrédients.NomIngrédient);
}
}
you could try something like this.
var results = _listIngredient.Join(_listRecette,
i => i.NoIngrédient,
r => r.NoIngrédient,
(ingre, rece) => new { ingre.NoIngrédient, ingre.NomIngrédient, ingre.PrixAuKilo, ingre.Périssable });

C# mimic associative array of unknown key-number (like in PHP)

Is there a possibility to create sth. like an associative array like in PHP?
I don't plan to create a game with some player-data, but I could easily explain this way what I want:
player["Name"] = "PName";
player["Custom"]["Gender"] = "Female";
player["Custom"]["Style"] = "S1";
player["Custom"]["Face"]["Main"] = "FM1";
player["Custom"]["Face"]["Eyes"] = "FE1";
player["Custom"]["Height"] = "180";
Also the length has to be dynamic, I don't how many keys there will be:
player["key1"]["key2"]=value
player["key1"]["key2"]["key3"]["key4"]...=value
What I need is sth. I could address like:
string name = player["Name"];
string gender = player["Custom"]["Gender"];
string style = player["Custom"]["Style"];
string faceMain = player["Custom"]["Face"]["Main"];
string faceEyes = player["Custom"]["Face"]["Eyes"];
string height = player["Custom"]["Height"];
Or in some way similar to this.
What I tried till now:
Dictionary<string, Hashtable> player = new Dictionary<string, Hashtable>();
player["custom"] = new Hashtable();
player["custom"]["Gender"] = "Female";
player["custom"]["Style"] = "S1";
But the problem starts here (only works with 2 keys):
player["custom"]["Face"] = new Hashtable();
player["Custom"]["Face"]["Main"] = "FM1";
C# is strongly typed so it seems not easy to replicate this exact behavior.
A "possibility" :
public class UglyThing<K,E>
{
private Dictionary<K, UglyThing<K, E>> dicdic = new Dictionary<K, UglyThing<K, E>>();
public UglyThing<K, E> this[K key]
{
get
{
if (!this.dicdic.ContainsKey(key)) { this.dicdic[key] = new UglyThing<K, E>(); }
return this.dicdic[key];
}
set
{
this.dicdic[key] = value;
}
}
public E Value { get; set; }
}
Usage :
var x = new UglyThing<string, int>();
x["a"].Value = 1;
x["b"].Value = 11;
x["a"]["b"].Value = 2;
x["a"]["b"]["c1"].Value = 3;
x["a"]["b"]["c2"].Value = 4;
System.Diagnostics.Debug.WriteLine(x["a"].Value); // 1
System.Diagnostics.Debug.WriteLine(x["b"].Value); // 11
System.Diagnostics.Debug.WriteLine(x["a"]["b"].Value); // 2
System.Diagnostics.Debug.WriteLine(x["a"]["b"]["c1"].Value); // 3
System.Diagnostics.Debug.WriteLine(x["a"]["b"]["c2"].Value); // 4

Refactoring similar methods using generics parameter in c# and linq

I have two methods they are exactly the same except the first parameter.I don't want to repeat the duplicate code. I was wondering how can we refactor the following code using generic parameters.
First method
private Dictionary<List<string>, List<string>> GetFinancialLtmDataSet(List<sp_get_company_balance_sheet_amount_ltm_Result> itemResult, int neededyear)
{
var requestedData =
itemResult.OrderByDescending(x => x.date.Year).Take(neededyear).Select(x => new { date = x.date.Date });
var addFields = new List<string>();
var dataSet = new Dictionary<List<string>, List<string>>();
int counter = 0;
foreach (var itemy in requestedData)
{
var skipvalue = itemResult.Skip(counter);
var columns = skipvalue.OrderBy(x => itemy.date).ToList();
var cc = columns.First();
counter++;
var properties =
cc.GetType()
.GetProperties()
.Select(x => new { Name = x.Name, Value = x.SetMethod, a = x.GetValue(cc, null) })
.ToList();
foreach (var property in properties)
{
addFields.Add(property.Name);
if (property.a != null)
{
dataSet.Add(new List<string> { property.Name }, new List<string> { property.a.ToString() });
}
}
}
return dataSet;
}
Second method
private Dictionary<List<string>, List<string>> GetFinancialQuartelyDataSet(List<sp_get_company_balance_sheet_amount_quaterly_Result> itemResult, int neededyear)
{
var requestedData =
itemResult.OrderByDescending(x => x.date.Year).Take(neededyear).Select(x => new { date = x.date.Date });
var addFields = new List<string>();
var dataSet = new Dictionary<List<string>, List<string>>();
int counter = 0;
foreach (var itemy in requestedData)
{
var skipvalue = itemResult.Skip(counter);
var columns = skipvalue.OrderBy(x => itemy.date).ToList();
var cc = columns.First();
counter++;
var properties =
cc.GetType()
.GetProperties()
.Select(x => new { Name = x.Name, Value = x.SetMethod, a = x.GetValue(cc, null) })
.ToList();
foreach (var property in properties)
{
addFields.Add(property.Name);
if (property.a != null)
{
dataSet.Add(new List<string> { property.Name }, new List<string> { property.a.ToString() });
}
}
}
return dataSet;
}
I have created a following method to make it generic but not been able to get the final implementation any suggestion appreciated.
private List<T> GetFinancialReport<T>(List<T> data, int neededyear)
{
//what should I return from here
return data;
}
and would like to use the above method like this
var balancesheetResult=balancesheet.ToList();
var testData = GetFinancialReport<BalanceSheet_sp>(balancesheetResult, 5);
var cashflowresult=cashflow.ToList();
var testData1 = GetFinancialReport<CahsFlow_sp>(cashflowresult, 10);
From what is shown above the objects (at least the properties involved) match. So you could code against an interface here:
private Dictionary<List<string>, List<string>> GetFinancialReport(List<IBalance>, int neededyear)
{
...
}

finding a member property of an item in an array

I've passed in the whole sale object into this function. In that sale object, there are many childs e.g. saleOrderItem, Payment, User...
sale.payment is an array
Question:
1) How do I get the CodeNo from the `sale.payment' object? (as payment is an array)
2) How to get the sale.payment.CourseByTutor.TutorId (as payment is an array)
public static object GetSalesDataBySaleOrderID(SaleOrder sale)
{
return sale.saleOrderItem
.Where(s => s != null)
.Select(s => new {
Id = s.Id,
Username = sale.User.GetSingleUserById(s.UserId).Name,
Amount = s.Amount,
CodeNo = s.SaleOrder.payment.First().CodeNo,
TutorName = sale.User.GetSingleUserById(s.SaleOrder.payment.FirstOrDefault().CourseByTutor.TutorId).Name,
})
.ToList();
}
Here is how i bind the value to the object
private void SaveValueToObject()
{
saleOrder.UserId = UserInfo.Id;
saleOrder.Date = DateTime.Now;
for (int i = 0; i < dgSale.Rows.Count; i++)
{
SaleOrderItem SaleItem = new SaleOrderItem();
SaleItem.InventoryTypeId = Convert.ToInt32(dgSale.Rows[i].Cells["inventoryTypeId"].Value);
SaleItem.InventoryOrCourseId = Convert.ToInt32(dgSale.Rows[i].Cells["inventoryId"].Value);
SaleItem.Qty = Convert.ToInt32(dgSale.Rows[i].Cells["qty"].Value);
SaleItem.Amount = Convert.ToDecimal(dgSale.Rows[i].Cells["total"].Value);
SaleItem.UserId = Convert.ToInt32(dgSale.Rows[i].Cells["userId"].Value);
SaleItem.Discount = Convert.ToDecimal(dgSale.Rows[i].Cells["discount"].Value);
SaleItem.Remarks = (dgSale.Rows[i].Cells["remark"].Value == null) ? "" : dgSale.Rows[i].Cells["remark"].Value.ToString();
SaleItem.Status = (int)SaleOrderStatus.Active;
saleOrder.saleOrderItem[i] = SaleItem;
Payment p = new Payment();
p.PayType = Convert.ToInt32(dgSale.Rows[i].Cells["payType"].Value);
p.Code = (int)PaymentCode.RCT; // For Receipt prefix
p.CodeNo = p.GetNewReceiptNo(p.Code); //Check if it is receipt, if yes, Get last Receipt No + 1
p.UserId = (txtUserId.Text == string.Empty) ? 0 : Convert.ToInt32(txtUserId.Text);
p.Amount = Convert.ToDecimal(dgSale.Rows[i].Cells["total"].Value);
p.Remark = (dgSale.Rows[i].Cells["remark"].Value == null) ? "" : dgSale.Rows[i].Cells["remark"].Value.ToString();
p.PaymentMethodId = saleOrder.PaymentMethodId;
p.DateIssue = saleOrder.Date;
p.CourseByTutor.TutorId = Convert.ToInt32(dgSale.Rows[i].Cells["tutorId"].Value);
saleOrder.payment[i] = p;
}
}
I have a workaround and solved this question by adding the desired properties e.g. TutorId in the sale.saleOrderItem class. Thus making the direct access to the sale.SaleOrderItem.TutorId.
This sound stupid but it works.

Categories