Reputation: 11354
I have 2 list ModelA
and ModelB
and sample data like below,
public class ModelA
{
public string ModelAName { get; set; }
public DateTime ModelATime { get; set; }
}
public class ModelB
{
public string ModelBName { get; set; }
public DateTime ModelBMinTime { get; set; }
public DateTime ModelBMaxTime { get; set; }
}
Sample Data,
var lstModelA = new List<ModelA>
{
new ModelA { ModelAName ="A1", ModelATime = new DateTime(2021, 04, 30)},
new ModelA { ModelAName ="A2", ModelATime = new DateTime(2021, 04, 29)},
new ModelA { ModelAName ="A6", ModelATime = new DateTime(2021, 03, 03)}
};
var lstModelB = new List<ModelB>
{
new ModelB { ModelBName ="A1", ModelBMinTime = new DateTime(2021, 01, 01), ModelBMaxTime = new DateTime(2021, 05, 05)},
new ModelB { ModelBName ="A2", ModelBMinTime = new DateTime(2021, 01, 01), ModelBMaxTime = new DateTime(2021, 04, 29)},
new ModelB { ModelBName ="A4", ModelBMinTime = new DateTime(2021, 04, 04), ModelBMaxTime = new DateTime(2021, 04, 05)}
};
I need to compare ModelB
against ModelA
where
If ModelBName
NOT exits in ModelAName
, I want to return this record with same ModelBMinTime
and ModelBMaxTime
time. (example: A4
)
If ModelBName = ModelAName
and ModelATime = ModelBMaxTime
, then I don't want to return this. (example 'A2')
var a= lstModelA.First(x => x.ModelAName == "A2").ModelATime;
var b = lstModelB.First(x => x.ModelBName == "A2").ModelBMaxTime;
Here a=b!
If ModelBName = ModelAName
and ModelATime != ModelBMaxTime
, then I want to return this result but ModelBMinTime should be replace with = ModelATime
. (Example A1
)
I tried this, looping each ModelB
and also try/catch since some ModelB
(A4) nt present in lstModelA
, how to get rid of it and improve this?
var data = new List<ModelB>();
foreach (var modelB in lstModelB)
{
try
{
var modelA = lstModelA.First(x => x.ModelAName == modelB.ModelBName);
if (modelA.ModelATime != modelB.ModelBMaxTime)
{
data.Add(new ModelB { ModelBName = modelB.ModelBName, ModelBMinTime = modelA.ModelATime, ModelBMaxTime = modelB.ModelBMaxTime });
}
}
catch (Exception)
{
data.Add(new ModelB { ModelBName = modelB.ModelBName, ModelBMinTime = modelB.ModelBMinTime, ModelBMaxTime = modelB.ModelBMaxTime });
}
}
Upvotes: 0
Views: 87
Reputation: 1066
What about a join, assuming you aren't dealing with static lists and they grow to larger sizes a join should give you better performance.
var data =
(from mb in lstModelB
join ma in lstModelA on
mb.ModelBName equals ma.ModelAName
into gj
from sma in gj.DefaultIfEmpty()
where sma is null || sma.ModelATime != mb.ModelBMaxTime
select new ModelB
{
ModelBName = mb.ModelBName,
ModelBMinTime = sma?.ModelATime ?? mb.ModelBMinTime,
ModelBMaxTime = mb.ModelBMaxTime
})
.ToList();
Upvotes: 1
Reputation: 4354
You just need to make a null check instead of try-catch as far as I can see
var modelA = lstModelA.FirstOrDefault(x => x.ModelAName == modelB.ModelBName);
if (modelA != null && modelA.ModelATime != modelB.ModelBMaxTime)
{
data.Add(new ModelB
{
ModelBName = modelB.ModelBName,
ModelBMinTime = modelA.ModelATime,
ModelBMaxTime = modelB.ModelBMaxTime
});
}
else if (modelA == null)
{
data.Add(new ModelB
{
ModelBName = modelB.ModelBName,
ModelBMinTime = modelB.ModelBMinTime,
ModelBMaxTime = modelB.ModelBMaxTime
});
}
however, if modelB might be null you need to check that also.
Upvotes: 1
Reputation: 147
Try using .FirstOrDefault()
and check your variable for null
afterwards:
var modelA = lstModelA.FirstOrDefault(x => x.ModelAName == modelB.ModelBName);
if (modelA == null)
{
// not found / does not exist
}
else
{
// found
}
Upvotes: 2