InvalidOperationException: Sequence contains more than one element - SingleOrDefault() - c#

using (var db = new ABC())
{
for (int column = rangeClass2.Start.Column; column <= rangeClass2.End.Column; column++)
{
var classValue = censusSheet.Cells[row, column].Value;
var description = censusSheet.Cells[3, 27].Value;
lifeReductionByData.Add(classASheet.getClassFromExcelPivotedValuedreductionBy<tbl_Life_Reduction_By>(25, 1, 33, 4, lifeReductionByClassMapper).FirstOrDefault());
for (int i = 0; i < lifeReductionByData.Count; i++)
{
lifeReductionByData[i].Class = classesValue[x];
lifeReductionByData[i].UUID = censusSheet.GetValue(25, 27).ToString();
}
}
var entry = new tbl_Life_Master() { UUID = uuidVar };
entry.tbl_Life_Reduction_By = lifeReductionByData;
context.tbl_Life_Master.Add(entry);
context.SaveChanges();
}
By searching on Stack Overflow, it is clear to me that FirstOrDefault() is the best approach to avoid this execption. But if I want to add multiple records in my list once then what is the solution? As 'getClassFromExcelPivotedValuedreductionBy' here is returning 3 records. Please help me out in this.

But if I want to add multiple records in my list once then what is the solution?
You mean you want to add all the results? Assuming that lifeReductionByData is a List<T> for the appropriate type, you can just use List<T>.AddRange:
var query = classASheet.getClassFromExcelPivotedValuedreductionBy<tbl_Life_Reduction_By>(25, 1, 33, 4, lifeReductionByClassMapper);
lifeReductionByData.AddRange(query);
foreach (var item in lifeReductionByData)
{
item.Class = classesValue[x];
item.UUID = censusSheet.GetValue(25, 27).ToString();
}
Note the use of foreach here instead of the index. Now, if lifeReductionByData was actually empty before this piece of code, and you don't need it afterwards, you can just iterate over the query itself:
var query = classASheet.getClassFromExcelPivotedValuedreductionBy<tbl_Life_Reduction_By>(25, 1, 33, 4, lifeReductionByClassMapper);
foreach (var item in query)
{
item.Class = classesValue[x];
item.UUID = censusSheet.GetValue(25, 27).ToString();
}
If you do need the list afterwards, but it was empty beforehand, then I'd use:
var query = classASheet.getClassFromExcelPivotedValuedreductionBy<tbl_Life_Reduction_By>(25, 1, 33, 4, lifeReductionByClassMapper);
var list = query.ToList();
foreach (var item in list)
{
item.Class = classesValue[x];
item.UUID = censusSheet.GetValue(25, 27).ToString();
}
Next up, I'd rename getClassFromExcelPivotedValuedreductionBy to a) be briefer; b) follow .NET naming conventions.

Related

How to fix extra run in loop?

I create an object in which values from 3 rows and I need to loop through 3 lines and add values from this object (rowsCmd).
private void CalculateDist()
{
var Unique= Cursor.GetFieldValue<int>("Unique");
var document = new HeadersRepository().Get(Unique);
if (document == null)
{
return;
}
var rowsRepository = new RowsRepository(document);
var rowList = rowsRepository.GetRows();
var cmd = SqlClient.Main.CreateCommand(string.Format(
#"select DOC.Unique, DOC.Number from DOC where DOC.Unique =#Unique order by DOC.Number"), new { Unique });
var rowsCmd = cmd.ExecObjects(new
{
Unique= 0,
Number= 0,
});
foreach (var row in rowList)
{
foreach (var rowCmd in rowsCmd)
{
row.Number = rowCmd.Number;
row.Number= rowCmd.Number;
}
}
}
if i have 2 rows this code will execute 4 time, but need only 2. how to make a loop which will pass through each rows in my list rowList and put data from object rowsCmd in 1 loop
Your code always set row values with rowsCmd list's last element. So it is a wrong code segment.
For your purpose you can use for loop instead of foreach loop.
for(int i=0; i< rowList.Count; i++){
rowList[i].Number = rowsCmd[i].Number;
}

Best way to remove value from list where property Id is contained in another list

What would be the best approach to remove a value from a list where the property Id is contained in another list.
I tried this but is not quote working the way as expected.
internal static List<DashboardData> CloseWhereOpen(List<DashboardData> rawData,
List<DashboardData> activitiesOpen)
{
var index = 0;
foreach (var val in rawData)
{
if (activitiesOpen.Select(ao=>ao.CanvasId == val.CanvasId).Count() > 0) {
rawData.ToList().RemoveAt(index);
}
index++;
}
return rawData;
}
I'm not sure if i understood your question correctly, but this should do the trick:
foreach (var val in activitiesOpen)
{
rawData.RemoveAll(x => x.CanvasId == val.CanvasId);
}
Example lists (with integers for simplification):
(before)
activitiesOpen = { 1, 3 }
rawData = { 1, 2, 3, 4, 5 }
(after)
rawData = { 2, 4, 5 }
You can get the canvasIds that need to be deleted and filter them out of the rawData list, then remove the whole range. i.e.
var canvasIds = activitiesOpen.Select(x => x.CanvasId).ToList();
var rawDataItemsToDelete = rawData.Where(x => canvasIds.Contains(x.CanvasId)).ToList();
rawData.RemoveRange(rawDataItemsToDelete);
ToList creates a new list, you want to remove from the existing.
I'd suggest this LINQ query:
rawData = rawData
.Where(d => !activitiesOpen.Any(ao => ao.CanvasId == d.CanvasId))
.ToList();
You are removing from a newly created List:
//new list //remove it
rawData.ToList().RemoveAt(index);
A quick fix could be:
rawData = rawData.ToList().RemoveAt(index);
But then you are changing your collection. So, a better way is to use an inverted for loop:
internal static List<DashboardData> CloseWhereOpen(List<DashboardData> rawData,
List<DashboardData> activitiesOpen)
{
var index = 0;
for (var i = rawData.Length -1; i >= 0; i--)
{
if (activitiesOpen.Select(ao=>ao.CanvasId == rawData[i].CanvasId).Count() > 0)
{
rawData.RemoveAt(index);
}
}
return rawData;
}
Or, just use one of the mentioned RemoveAll, RemoveRange methods ;-)

How i foreach loop in listitems values entity framework

I have 2 lists. One has 3 records like 1 , 2 , 3 and seconds list holds table records. All i wanna do add first list values to second list.
I hope helps.
foreach (var itemAgent in listofValues)
{
foreach (var item in formSorgu)
{
#region MyRegion
CrmDonusleri crmEkleme = new CrmDonusleri()
{
AradigiBolge = item.bolge,
AramaTarihi = Convert.ToDateTime(item.aratarihi),
Musno = item.musno,
GeriDonusYapildiMi = false,
AtanmaTarihi = DateTime.Now,
KanalAdi = item.kanal,
ProgramAdi = item.program,
AtananAgent = itemAgent
};
DbContext.CrmDonusleri.Add(crmEkleme);
#endregion
}
}
DbContext.SaveChanges();
listofValues hold 3 records and formSorgu hold 2000 records. listofValues as List One and formSorgu as List Two. And i want my final list like Picture below.
I don't think my code is right. Please show me the right way to write this query.
for (int i = formSorgu.Count + 1; i >= 0; i--)
{
foreach (var itemAgent in listofValues)
{
CrmDonusleri crmEkkle = new CrmDonusleri()
{
Musno = formSorgu.FirstOrDefault().musno,
AtananAgent = itemAgent
};
}
}
when i use this code it gets one record from formSorgu but add to listofValues 3 times i just want it to foreach one time and go out from foreach loop and carry on other for loop record.
actually, i love to share i am not like stackover mods. so i found an excellent answer on internet. you can find a link that equally selecting items from list and psuedo run.
solution link
that is a link i used. and i turn my code like this;
var randoAgent = new RandomPicker<string>(listofValues);
foreach (var itemSorgu in formSorgu)
{
var item = randoAgent.PickItem();
CrmDonusleri crmEkle = new CrmDonusleri()
{
Musno = itemSorgu.musno,
TelNo = itemSorgu.telno,
AtananAgent = item,
AradigiBolge = itemSorgu.bolge,
AramaTarihi = Convert.ToDateTime(itemSorgu.aratarihi),
AtanmaTarihi = DateTime.Now,
Ekleyen = itemSorgu.ekleyen,
GeriDonusYapildiMi = false,
KanalAdi = itemSorgu.kanal,
ProgramAdi = itemSorgu.program
};
DbContext.CrmDonusleri.Add(crmEkle);
}
DbContext.SaveChanges();
and works perfect.

How can I compare an index value of a list item with all index of same list

i have a list which is iterating multiple times. it is having rangename as item. My requirement is perform an action when rangename at any index of this list is equal to rangename at some other index. i am using the following code.
var bList = new List<Budget.budget_data>();
for (int z = 0; z < bList.Count; z++)
{
if (bList [z].Range == bList.Where(a => bList.Any(x => x.Range ==x.Range)))
{
//need to perform action
}
}
which is giving error. How to compare one index value of a list's item with all index on same list .
From what I understand from your question, you want to perform some action when two Ranges are equal in your list. Following should work for you.
var bList = new List<Budget.budget_data>();
for (var i = 0; i < bList.Count; i++)
{
for (var j = i + 1; j < bList.Count; j++)
{
if (bList[i].Range == bList[j].Range)
{
//Perform your action
}
}
}
This will perform your action if there is any duplicate Range in the list.
Sounds like you are trying to find duplicates however without clearly knowing what you are trying to achieve its difficult to help you find an adequate solution to your problem.
Using some of the details you've provided, below is a generic solution for looping through duplicates.
public static void Main()
{
var budgets = new List<Budget>()
{
new Budget(){ Id = 1, Range = "A" },
new Budget(){ Id = 2, Range = "B" },
new Budget(){ Id = 3, Range = "C" },
new Budget(){ Id = 4, Range = "C" },
new Budget(){ Id = 5, Range = "A" }
};
var duplicateBudgetGroups = budgets.GroupBy(budget => budget.Range).Where(group => group.Count() > 1);
foreach (var duplicateBudgets in duplicateBudgetGroups)
{
Console.WriteLine("Duplicate Range {0}", duplicateBudgets.Key);
foreach (var budget in duplicateBudgets)
{
Console.WriteLine("Budget {{ Id = {0}, Range = {1} }}", budget.Id.ToString(), budget.Range);
}
}
}
class Budget {
public int Id { get; set; }
public string Range { get; set; }
}
I've added this to dotnetfiddle so you can see it working: https://dotnetfiddle.net/65gF6f
Not too clearly asked, I feel, but you could try this:
var bList = new List<Budget.budget_data>();
// ...
var z = ...;
for (var x = 0; x < bList.Count; ++x)
{
if (x == z)
continue;
if (bList[z].Range == bList[x].Range)
{
//need to perform action
}
}
This performs the action one time for each index x for which there is a match, so the action can run many times. If you just want one execution of the action, you may finish the if block with a break; statements (exits the loop completely).
Note: This assumes that the type of .Range is such that it is reasonable to use ==. What is the declared type of .Range?
I may have misunderstood the question. If you want to determine whether there are any duplicates at all, you can:
var bList = new List<Budget.budget_data>();
// ...
var uniqueRangeValues = new HashSet<string>();
foreach (var b in bList)
{
if (!uniqueRangeValues.Add(b.Ranges))
{
// perform action
break; // omit if you want to perform the action several times
}
}

How to iterate through IEnumerable collection using for each or foreach?

I want to add one by one values but in for loop how can I iterate
through one by one values and add it inside dictionary.
IEnumerable<Customer> items = new Customer[]
{
new Customer { Name = "test1", Id = 111},
new Customer { Name = "test2", Id = 222}
};
I want to add { Name = "test1", Id = 111} when i=0
and want to add { Name = "test2", Id = 222} when i=1 n so on..
Right now i'm adding full collection in every key.(want to achieve this using foreach or forloop)
public async void Set(IEnumerable collection)
{
RedisDictionary<object,IEnumerable <T>> dictionary = new RedisDictionary>(Settings, typeof(T).Name);
// Add collection to dictionary;
for (int i = 0; i < collection.Count(); i++)
{
await dictionary.Set(new[] { new KeyValuePair<object,IEnumerable <T> ( i ,collection) });
}
}
If the count is need and the IEnumerable is to be maintained, then you can try this:
int count = 0;
var enumeratedCollection = collection.GetEnumerator();
while(enumeratedCollection.MoveNext())
{
count++;
await dictionary.Set(new[] { new KeyValuePair<object,T>( count,enumeratedCollection.Current) });
}
New version
var dictionary = items.Zip(Enumerable.Range(1, int.MaxValue - 1), (o, i) => new { Index = i, Customer = (object)o });
By the way, dictionary is a bad name for some variable.
I'm done using
string propertyName = "Id";
Type type = typeof(T);
var prop = type.GetProperty(propertyName);
foreach (var item in collection)
{
await dictionary.Set(new[] { new KeyValuePair<object, T>(prop.GetValue(item, null),item) });
}
So you want to a an item from the collection to the dictionary in the for loop?
If you cast your IEnumerable to a list or an array, you can easily access it via the index. For example like this:
Edit: Code at first created a list every time it looped, which should of course be avoided.
var list = collection.ToList(); //ToArray() also possible
for (int i = 0; i < list.Count(); i++)
{
dictionary.Add(i, list[i]);
}
I'm not 100% if that is what you need, though. More details to your question would be great.

Categories