C# LINQ leftjoin remove Invalid record - c#

I have 2 Datatables:
PreviousDayData
ID Account IsEmail EmailAddress
1 1111 N abc1Invalid#gmail.com // Invalid email
2 1112 Y abc2#gmail.com // Valid email
3 1113 Y abc3#gmail.com // Valid email
CurrentDayData
ID Account IsEmail EmailAddress
1 1111 Y abc1Changed#gmail.com // Valid email value changed
2 1112 Y abc2#gmail.com // Valid email
3 1113 Y abc3Changed#gmail.com // Valid email value changed
4 1114 N NULL // Invalid email
I am doing leftjoin CurrentDay with PreviousDay:
Conditions:
1. "ID" and "Account" of CurrentDay must match with "ID" and "Account" of PreviousDay
2. "IsEmail" OR "EmailAddress" value has changed from PreviousDay
The below query returns ResultData:
ID Account IsEmail EmailAddress
1 1111 Y abc1Changed#gmail.com // Valid email
3 1113 Y abc3Changed#gmail.com // Valid email
4 1114 N NULL // Invalid email
var ResultData = (from rowCurrent in currentDay.AsEnumerable()
join rowPrevious in previousDay.AsEnumberable()
on new { ID = rowCurrent.Field<string>("ID"), Account = rowCurrent.Field<string>("Account") }
equals new { ID = rowPrevious .Field<string>("ID"), Account = rowPrevious .Field<string>("Account") }
into rowRight
from rowJoin in rowRight.DefaultIfEmpty()
where
(rowCurrent.Field<string>("IsEmail") != rowJoin?.Field<string>("IsEmail")) ||
(rowCurrent.Field<string>("EmailAddress") != rowJoin?.Field<string>("EmailAddress"))
select new ResultData
{
ID = rowCurrent.Field<string>("ID"),
Account = rowCurrent.Field<string>("Account"),
IsEmail = rowCurrent.Field<string>("IsEmail"),
EmailAddress = rowCurrent.Field<string>("EmailAddress")
}
).ToList();
Question: How do I remove only the new record in CurrentDay from ResultData if it is not valid.
ID Account IsEmail EmailAddress
4 1114 N NULL // Invalid email
If there is a new record in CurrentDay that is not present in PreviousDay, I need to check "IsEmail" != "Y" OR "EmailAddress" is not a validEmail, then I do not want to include in the ResultData.
Note: I have a helper method to check Valid Email address string.

I tried the following query for left join:
var ResultData = (from rowCurrent in currentDay.AsEnumerable()
join rowPrevious in previousDay.AsEnumberable()
on new { ID = rowCurrent.Field<string>("ID"), Account = rowCurrent.Field<string>("Account") }
equals new { ID = rowPrevious .Field<string>("ID"), Account = rowPrevious .Field<string>("Account") }
into rowRight
from rowJoin in rowRight.DefaultIfEmpty()
where
rowJoin == null ?
(
(rowCurrent.Field<string>("IsEmail") == "Y") &&
(IsValidEmail(rowCurrent.Field<string>("EmailAddress")))
) :
(
(rowCurrent.Field<string>("IsEmail") != rowJoin?.Field<string>("IsEmail")) ||
(rowCurrent.Field<string>("EmailAddress") != rowJoin?.Field<string>("EmailAddress"))
)
select new ResultData
{
ID = rowCurrent.Field<string>("ID"),
Account = rowCurrent.Field<string>("Account"),
IsEmail = rowCurrent.Field<string>("IsEmail"),
EmailAddress = rowCurrent.Field<string>("EmailAddress")
}
).ToList();
-- If a non-matching row is found, it will select only if it is a Valid Record.
OR ELSE
-- If a matching row is found, it will select if "IsEmail" OR "EmailAddress" value has changed from PreviousDay

Related

How to get Role Based on the email and password

Please Help me How can i get Role when my UserName & password match.
I Have Below Data
LoginCredentialTab
Id UserName Psw Role
1 ADAM 123 Admin
2 John 456 Hr
In My Repo Class I writen as
public bool Login(LoginCrediential Login)
{
var x = (from n in db.LoginCrediential
where n.UserName == Login.UserName && n.Password == Login.Password select n).FirstOrDefault();
if (x != null)return true;
else return false; //Here How can i get Roles When UserName & Psw Match
You can't use the role after you return a value.
public bool Login(LoginCrediential Login)
{
var x = (from n in db.LoginCrediential
where n.UserName == Login.UserName && n.Password == Login.Password select n).FirstOrDefault();
if (x != null){
var roleOfTheUser = x.Role;
return true;}
else return false;

How to extract child groups from parent and re group using Linq

I have strange requirement. I am grouping records on the basis of certain criteria ( e.g Gln and other fields...) For each group I have further list of objects. I realized that few object from those list must be separated and need to replicate another group with the same Gln. Because, those objects should not be placed there. They must formulate another group with the same key ( i.e Gln ).
Please have a look on following code.
var claimsQuery = (from consignment in Consignments
let consigneeAddress = consignment.ConsignmentAddresses.FirstOrDefault(pr => pr.AddressTypeId == 2)
where (consignment.ClientId == 26 && consignment.FixDate != null )
group consignment by new
{
consigneeAddress.GLN,
consignment.ForwarderId,
consigneeAddress.Country.ISO,
consignment.FixDate,
ProductName = Products.FirstOrDefault(pr => pr.ProductId == consignment.ProductId).Name,
ProductId = consignment.ProductId
}
into g
select new DepoOverviewData
{
ForwarderId = g.Key.ForwarderId,
FixDate = g.Key.FixDate.GetValueOrDefault(),
Gln = g.Key.GLN,
ProductName = g.Key.ProductName,
ConsignmentsOverviewData =
(from singleConsignment in Consignments.Where(pr => ( pr.FixDate == g.Key.FixDate) && ( pr.ProductId == g.Key.ProductId))
join x in ConsignmentAddresses on singleConsignment.ConsignmentId equals x.ConsignmentId
where x.GLN == g.Key.GLN && x.AddressTypeId == 2
select new ConsignmentClaimsOverviewData()
{
ConsignmentId = singleConsignment.ConsignmentId,
Weight = singleConsignment.Weight,
ChargeableWeight = singleConsignment.ChargeableWeight,
TotalCost = singleConsignment.NetTotalCost,
ProductId = singleConsignment.ProductId,
ProductName = Products.FirstOrDefault(pr => pr.ProductId == singleConsignment.ProductId).Name,
FixDate = singleConsignment.FixDate,
ExpressTime = singleConsignment.ExpressTime,
ClientOrderNumber = singleConsignment.ClientOrderNumber,
DeliveryDate = singleConsignment.DeliveryDate,
InTime = false, // this will be reset later. ( i.e True, false or null after iterating again over each group ).
}).ToList()
}).ToList();
I also attached one image to demonstrate things.
Since you fail to specify the criteria for when a group has to be split into two (or several), let me give you a generic example.
The idea behind it is to add another property to the grouping key that indicates the belonging to a "group in the group". I use bool to split groups into two, but of course this can be changed to a type having more than just two values.
If the input is like
var input = new[] {
new { Key = 1, Value = 42 },
new { Key = 1, Value = 101 },
new { Key = 1, Value = 99 },
new { Key = 2, Value = 999 },
new { Key = 2, Value = 1001 },
new { Key = 3, Value = 4711 }
};
and the rule for whether to create a separate group is
private static bool NeedsSeparateGroup(int key, int value)
{
switch (key)
{
case 1: return value > 100;
case 2: return value > 1000;
default: return false;
}
}
then just group also by what specifies the group-in-group belonging (don't like query syntax, but of course you can use it):
var result = input
.GroupBy(raw => new
{
raw.Key,
IsSeparateGroup = NeedsSeparateGroup(raw.Key, raw.Value)
}, (k, vs) => new
{
k.Key,
k.IsSeparateGroup,
Values = vs.Select(r => r.Value).ToList()
});
giving
Key: 1, IsSeparateGroup: False, Values: 42,99
Key: 1, IsSeparateGroup: True, Values: 101
Key: 2, IsSeparateGroup: False, Values: 999
Key: 2, IsSeparateGroup: True, Values: 1001
Key: 3, IsSeparateGroup: False, Values: 4711

How to get the group sum in my complex linq query

below I have listed a linq query that works properly in my asp.net.mvc web app.
In addition I would like to group over 'allowance.ParameterId' in order to get the group sum for 'allowance.Freight (instead of multiple records for the given key).
var query = from ara in aras
join company in companies on ara.Id equals company.ARAId
join wasteWater in wasteWaters on company.Id equals wasteWater.CompanyId
join allowance in allowances on wasteWater.Id equals allowance.WasteWaterID
join parameter in parameters on allowance.ParameterId equals parameter.Id into JoinedParameterAllowance
from parameter in JoinedParameterAllowance.DefaultIfEmpty()
where company.Activ == true && company.End == null && company.Template == false
&& wasteWater.End == null
select new FreightSummaryViewModel
{
AraName = ara.Name,
AraId = ara.Id,
AllowedParameter = parameter.Name,
AllowedFreight = allowance.Freight
};
I have tried to insert 'group ...' but failed to get it right.
Could someone help me please to set up the proper syntax?
Thank you in advance, Manu
I have little idea about relations in your database, so I improvised...
// Some dummy data to play with
var aras = Enumerable.Range(0, 5).Select(i => new { Id = i, Name = "Ara" + i });
var companies = Enumerable.Range(0, 15).Select(i => new { Id = i, ARAId = i % 5, Activ = true, End = (DateTime?)null, Template = false });
var wasteWaters = Enumerable.Range(0, 35).Select(i => new { Id = i, CompanyId = i / 15, End = (DateTime?)null });
var allowances = Enumerable.Range(0, 70).Select(i => new { Id = i, WasteWaterID = i, ParameterId = i % 4, Freight = i * 1000 });
var parameters = Enumerable.Range(0, 4).Select(i => new { Id = i, Name = "Parameter" + i });
And this is what I believe you looked for:
var query =
from ara in aras
join company in companies on ara.Id equals company.ARAId
join wasteWater in wasteWaters on company.Id equals wasteWater.CompanyId
join allowance in allowances on wasteWater.Id equals allowance.WasteWaterID
join parameter in parameters on allowance.ParameterId equals parameter.Id
into JoinedParameterAllowance
// from parameter in JoinedParameterAllowance.DefaultIfEmpty()
where true
&& company.Activ == true
&& company.End == null
&& company.Template == false
&& wasteWater.End == null
group allowance by new
{
AraName = ara.Name,
AraId = ara.Id,
ParameterId = allowance.ParameterId
} into myGroup
select new //FreightSummaryViewModel
{
AraName = myGroup.Key.AraName,
AraId = myGroup.Key.AraId,
AllowedParameter = myGroup.Key.ParameterId,
AllowedFreight = myGroup.Sum(g => g.Freight)
};

how to Filter one list based on another lists field

I am fetching data from database from separater tables and storing in separate variables.
this is first list
var res = (from v in context.MasterValues
join c in context.MasterCategories on v.Category_Id equals c.Id
where c.Model_Key == (int)model && c.Name == tableName && v.Version_Id == version && v.Active == "Y" && c.Name.Equals("FXRates")
select new
{
Id = v.Id,
VersionId = v.Version_Id,
Text1 = v.Text1,
}).ToList();
This is second list
var fxview = context.MasterFXRates.Select
(x => new
{
Currency_code = x.Currency_code,
Rate = x.Rate,
Effective_dt = x.Effective_dt
}
).ToList();
So now How to filter Data from my second list fxview based on data from my first list ?
i.e.
i need to filter data where Currency_code's data of list2 matches with Text1 of List1 where effective_dt(datetime column) is maximum/Latest date
For Example if second lists data has
ABC , 100 , 2010-10-10
ABC , 120 , 2014-12-12
DEF ,700 , 2013-08-02
DEF ,500 ,2015-06-06
And List 1(res) has following data
1 , 1 , ABC
2 , 1 , DEF
So after filtering my final list must have following output
ABC ,120 (Since 2014-12-12 is latest date , the corresponding value is fetched and duplicate value (ABC,100) should be filtered.)
2.DEF ,500 (Since 2015-06-06 is latest date , the corresponding value is fetched and duplicate value (DEF,&00) should be filtered.)
var result = from masterFxRate in masterFxRates
join masterValue in masterValues on masterFxRate.Currency_code equals masterValue.Text1
group masterFxRate by
new
{
masterFxRate.Currency_code
} into groupedRates
select new
{
groupedRates.Key.Currency_code,
Rate = groupedRates.FirstOrDefault(g => g.Effective_dt != null
&& g.Effective_dt == groupedRates.Max(c => c.Effective_dt)).Rate
};
foreach (var item in result)
{
Console.WriteLine("{0} : {1} ", item.Currency_code, item.Rate);
}
fxView = fxView.OrderByDescending(x => x.effectiveDate).ToList();
var result = new List();
res.ForEach((x) => result.Add(fxView.First(y => x.text1 == y.currency_code)));
If effectiveDate is already a DateTime this should work otherwise convert it to a DateTime
var fxview = context.MasterFXRates.Select
(x => new
{
Currency_code = x.Currency_code,
Rate = x.Rate,
Effective_dt = Convert.ToDateTime(x.Effective_dt)
}
).ToList();

How find Max in a query with a join

I created this query, and I don't know how find the last date_attribution
var usertmp = from user in entity.inv_utilisateur
join userbadgetmp in entity.inv_utilisateur_badge on user.u_id equals userbadgetmp.u_id into gj
from userbadge in gj.DefaultIfEmpty()
select new UserEJ
{
u_id = (int) user.u_id,
name = user.name,
date_attrib = userbadge.date_attribution // here I want find the last date
};
for exemple if I have this 2 tables:
inv_utilisateur inv_utilisateur_badge
u_id name u_id date_attribution
1 name1 1 20130911
1 20130807
2 name2 2 20120608
3 name3
I need the result
u_id name date_attribution
1 name1 20130911
2 name2 20120608
3 name3
Edit 1
the type of the field are :
u_id : int,
name : string,
date_attribution : datetime
var usertmp = from user in entity.inv_utilisateur
join userbadgetmp in entity.inv_utilisateur_badge on user.u_id equals userbadgetmp.u_id into gj
from userbadge in gj.DefaultIfEmpty()
group userbadge by new{user.u_id, user.name} into g
select new UserEJ {
u_id = (int)g.Key.u_id,
name = g.Key.name,
date_attrib = g.Max(x => x!= null ? x.date_attribution : <a defaultvalue>)
}
you could also do
var usertmp = from user in entity.inv_utilisateur
let max_dt = (from userbadge in entity.inv_utilisateur_badge
where user.u_id == userbadge.u_id
select userbadge.date_attribution).Max()//??someDefaultvalue if you don't want null
select new UserEJ {
u_id = user.u_id,
name = g.name,
date_attrib = max_dt
}
Sorry for my answer but i am not used in the from clause:
var usertmp = entity.inv_utilisateur
.Join
(
entity.inv_utilisateur_badge,
x=>x.u_id,
x=>x.u_id,
(user,userbadge) => new
{
u_id = user.u_id,
name = user.name,
date_attrib = userbadge.date_attribution
}
)
.GroupBy(x=>new {x.u_id,x.name})
.Select
(
x => new
{
x.Key.u_id,
x.Key.name,
date_attrib = x.Max(z=>z.date_attrib)
}
);

Categories

Resources