Lambda Expression to get records from list in a list - list

I have a class as following:
public class Wrapper
{
public Wrapper();
public Class1 c1 { get; set; }
public List<Class2> lstC2 { get; set; }
}
where Class2 is :
public class Class2
{
public DateTime date1 { get; set; }
}
and I get the list of objects of Wrapper class by some method
List<Wrapper> lstWrap = SomeMethod();
Now I want to remove All the records from lstWrap where date1 is less than today for any record in lstC2 using lambda expression. I tried using RemoveAll function but could not meet the results.
Thank You.

in these situations I would use .All() or .Any()
var lts = new List<Wrapper>();
var res = lts.Where (l => l.lstC2.All(d => d.date1 >= DateTime.Now));
EDIT:
To remove all I would still use the .Any()
lstWrap.RemoveAll(l => l.lstC2.Any(a => a.date1 < DateTime.Now));

if you want to delete the item with at least one date which less than today,use:
lstWrap.RemoveAll(l=>l.lstC2.Count(d=>d.date1<DateTime.Today)>0);

Related

How to get distinct values from 2 different columns in the same list

So as you can see from the code bellow i have a list object named Matches, from which i would like to get a single list of the distinct teams, both from HomeTeam and AwayTeam. I'm trying to use LINQ and i can get a list of distinct teams if i only use HomeTeam parameter or AwayTeam parameter but not both together.
Thank you.
public class Match
{
public int ID { get; set; }
public string Country { get; set; }
public string Championship { get; set; }
public string Seasson { get; set; }
public DateTime MatchDate { get; set; }
public string HomeTeam { get; set; }
public int HomeScore { get; set; }
public int AwayScore { get; set; }
public string AwayTeam { get; set; }
}
private List<Match> Matches;
Matches = dataAccess.GetAllMatches();
I'm Trying to do something like that:
result = Matches.Select(HomeTeam, AwayTeam).Distinct().ToList();
At the risk that this smells like homework, a hint rather than code. Get your Home teams, Union your Away teams and apply a Distinct to the result.
So i finally come up with this solution.
Notice that now i need also to get not only the team but the country which the team belongs to.
public class Team
{
public string Name { get; set; }
public string Country { get; set; }
}
So Union really do the job here but since now i need to get it as an anonymous type... here is the code:
List<Team> teams = new List<Team>();
var result = Matches.Select(x => new { Name = x.HomeTeam, Country = x.Country }).Union(Matches.Select(x => new { Name = x.AwayTeam, Country = x.Country })).ToList();
foreach (var record in result)
{
teams.Add(new Team { Name = record.Name, Country = record.Country });
}
return teams;
I would prefer this way:
List<Team> teamsResult = Matches.Select(x => new Team { Name = x.HomeTeam, Country = x.Country }).Union(Matches.Select(x => new Team { Name = x.AwayTeam, Country = x.Country })).ToList();
But this way get duplicates so i will stick with the first example for now.
Do you think it is the more elegant way to go?
Thank you.
You can take advantage of GroupBy, like this:
IEnumerable<Team> teams = Matches.GroupBy(m => new { m.AwayTeam, m.HomeTeam, m.Country })
.Select(
g =>
new[]
{
new Team {Country = g.Key.Country, Name = g.Key.AwayTeam},
new Team {Country = g.Key.Country, Name = g.Key.HomeTeam}
})
.SelectMany(x => x)
.GroupBy(t => new { t.Name, t.Country })
.Select(g => new Team { Name = g.Key.Name, Country = g.Key.Country });

how to convert List<KeyValuePair<string,object>> to class, model in .Net Core

I have got response List<List<KeyValuePair<string, object>>> but I want to convert response into List<ClassName>.
KeyValuePair key and ClassName property both are same name and same type
What is the most programmatically way to convert response?
I have got response
My class structure
public class TestModel
{
public string TaxablePersonCode { get; set; }
public string LegalNameAsPerPan { get; set; }
public string TradeName { get; set; }
public string ConstitutionName { get; set; }
public string ResidentialStatusName { get; set; }
public string PrimaryMobileNo { get; set; }
public string FlatOrOfficeNo { get; set; }
public string TownOrCityOrDist { get; set; }
public string Pincode { get; set; }
public string StateName { get; set; }
public string CountryName { get; set; }
public string ContactName { get; set; }
public string ContactDesignationName { get; set; }
public string ContactMobile { get; set; }
public string ContactEmail { get; set; }
}
var listKeyValue = response.Select(x => x.Value).ToList();
var data = JsonConvert.DeserializeObject<List<TestModel>>(listKeyValue);
The only part of this im unsure about is when indexing the final list for the correct property, but you can choose what works best for you. Using a .Where() every time ensures you'll get the right result but it will search the list every single time and be a lot slower. If your %100 certain the order of the list will never change you could gain some performance by directly indexing the list for the element you want using [] or .ElementAt(). Anyway, heres what your looking for.
List<TestModel> myList = response.Select(x => new TestModel
{
// Using Where
TaxablePersonCode = x.Where(t => t.Key == "TaxablePersonCode").First().Value,
// Using direct index
LegalNameAsPerPan = x[1].Value,
// Using ElementAt
TradeName = x.ElementAt(2).Value,
...
});
Hope that helps!
Did you get some result with JsonConvert class? Did it worked for you? If not, you can try out something like this (if JSON and field are properly named):
var listKeyValue = response.Select(x => x.Value).ToList();
var result = new List<TestModel>();
foreach (var keyValueList in listKeyValue)
{
// convert the response list of KeyValuePair to dictionary
var dictionary = keyValueList.ToDictionary(kv => kv.Key, kv => kv.Value);
var tempModel = new TestModel();
// get actual value by name of the rpoperty
tempModel.TaxablePersonCode = dictionary[nameof(tempModel.TaxablePersonCode)].ToString();
// etc.
result.Add(tempModel);
}
Maybe this approach could be improved with reflection, but this will degrade the performance.
// get all properties to populate
var properties = typeof(TestModel).GetProperties(BindingFlags.Public | BindingFlags.Instance);
I see you're using JSON, so you should probably just deserialize the object properly, which I would expect to look something like this:
List<TestModel> models = JsonConvert.DeserializeObject<List<TestModel>>(response);
Otherwise, you could use reflection to bind the known KeyValuePair keys to the properties of the object; that being said, you will need to ensure that the return values are compatible with the values from the returned data, else this will fail.
outerList.ForEach(innerList => {
TestModel result = new TestModel();
innerList.ForEach(listItem => {
result
.GetType()
.GetProperty(listItem.Key)
?.SetValue(result, listItem.Value);
});
});

How to get distinct records from a list

I have a list of type Myclass
List<Myclass> liSubjectIdDetail = new List<Myclass>();
where Myclass looks like
public class Myclass
{
public Nullable<decimal> SubjectId { get; set; }
public string SubjectName { get; set; }
}
I am adding records into liSubjectIdDetail from a table
foreach (decimal Id in VarCEMSIdDetail)
{
liSubjectIdDetail.AddRange(db.Stt.MyTable.Where(x => x.Id == Id).Select(x => new Myclass { SubjectId = x.SubjectId, SubjectName = x.SubjectName }).ToList());
}
where Id contains a list of certain Ids on the basis of which records I fetch.
Now I want to get only distinct records in this list.
I have tried it with hashtable in place of List
and I also tried
liSubjectIdDetail= liSubjectIdDetail.Distinct().ToList();
but this too, is not working. Please give me a better solution.
Thanks in advance
Try this extension method
public static class IEnumerableExtensions {
public static IEnumerable<TSource> DistinctBy<TSource, TKey>
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var seenKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
if (seenKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
}
Usage:
liSubjectIdDetail= liSubjectIdDetail.DistinctBy(s => s.SubjectName).ToList();

Automoq Documentation

I am getting started with Automoq. I was trying to do something like this:
mocker.GetMock<IMyObjectToTweak>();
var line = mocker.Resolve<IMyObjectToTweak>();
line.PropertyOne = .75;
line.PropertyTwo = 100;
MyCalc calc = new MyCalc();
calc.Multiply(line);
Assert.AreEqual(75, line.result);
This runs bu fails. My properties do not get set. Am I missing the idea of Automoq? What is a good resource/tutorial?
To set property with Moq (this is what Automoq uses to create mock objects) you have to use different calls, - Setup, SetupGet or SetupProperty:
var line = mocker.Resolve<IMyObjectToTweak>();
// each does the same thing - "tells" PropertyOne to return .75 upon get
line.Setup(l => l.PropertyOne).Returns(.75);
line.SetupGet(l => l.PropertyOne).Returns(.75);
line.SetupProperty(l => l.PropertyOne, .75);
I suggest expose a Result property in your Sut (System Under test)
[TestClass]
public class SomeTest : ControllerTestBase
{
[TestMethod]
public void MethodNameOrSubject_ScenarioOrCondition_ExpectedBehaviourOrReturnValue()
{
var mock = _autoMoqContainer.GetMock<IMyObjectToTweak>();
var line = _autoMoqContainer.Resolve<IMyObjectToTweak>();
mock.Setup(x => x.PropertyOne).Returns(.75);
mock.Setup(x => x.PropertyTwo).Returns(100);
MyCalc calc = new MyCalc();
calc.Multiply(line);
Assert.AreEqual(75, calc.Result);
}
}
public interface IMyObjectToTweak
{
double PropertyOne { get; set; }
int PropertyTwo { get; set; }
}
public class MyCalc
{
public double Result { get; set; }
public void Multiply(IMyObjectToTweak line)
{
Result = line.PropertyOne*line.PropertyTwo;
}
}
Not related - But read my post more on AutoMocking
http://www.dotnetcurry.com/ShowArticle.aspx?ID=767

Unit testing of WF code activity

I have created coded activity and now I want to unit test it, but I do not know how.
Any example will be appreciated.
My simple example is below.
public sealed class ParameterActivity : CodeActivity
{
public InArgument<int> Argument1 { get; set; }
public InArgument<int> Argument2 { get; set; }
public OutArgument<int> Result { get; set; }
protected override void Execute(CodeActivityContext context)
{
var a = context.GetValue(Argument1);
var b = context.GetValue(Argument2);
context.SetValue(Result, a + b);
}
}
First of all, in case your activity returns a single value, just inherit from CodeActivity<TResult> and easily override Execute() with TResult as return type. Moreover, you've already available an OutArgument<TResult> Result.
public sealed class ParameterActivity : CodeActivity<int>
{
public InArgument<int> Argument1 { get; set; }
public InArgument<int> Argument2 { get; set; }
protected override int Execute(CodeActivityContext context)
{
var a = Argument1.Get(context);
var b = Argument2.Get(context);
return a + b;
}
}
That being said, WorkflowInvoker is the way to go to unit test almost all your activities. Taking above custom code activity as example:
[TestFixture]
public sealed class ParameterActivityTests
{
[Test]
public void ParameterActivity_Test()
{
var activity = new ParameterActivity();
var input1 = new Dictionary<string, object>
{
{ "Argument1", 10 },
{ "Argument2", 5 }
};
var input2 = new Dictionary<string, object>
{
{ "Argument1", -13 },
{ "Argument2", 3 }
};
var output1 = WorkflowInvoker.Invoke<int>(activity, input1);
var output2 = WorkflowInvoker.Invoke<int>(activity, input2);
Assert.That(output1, Is.EqualTo(15));
Assert.That(output2, Is.EqualTo(-10));
}
}
Rather than WorkflowInvoker you can also use WorkflowApplication but for unit testing that doesn't seem at all necessary when you just want to quickly invoke short-lived workflows for them to do "their thing" and return. Unless you want to test more elaborate stuff like asynchronous workflows and/or bookmarks.
You'll also want to check Microsoft.Activities.UnitTesting.