How to write simple code in LInq - c#

I have the following in my NotSelectedList.
public List<TestModel> SelectedList = new List<TestModel>();
public List<TestModel>NotSelectedList = new List<TestModel>();
NotificationDetailsModel projects = new NotificationDetailsModel();
projects.ProjectID = Convert.ToInt32(Row["ProjectID"]);
projects.Valid= Convert.ToBoolean(Row["Validity"]);
NotSelectedList.Add(projects);
How can I write a simple code in LINQ to select from the NotSelectedList where Validity == True and store the data in SelectedList?

var query = from ns in NotSelectedList
from n in SelectedList
where ns.Valid && ns.ProjectID == n.ProjectID
select ns;
Hope this will help you

The following would select the items with Validity = true from NotSelectedList and place them in SelectedList:
SelectedList.AddRange(NotSelectedList.Where(item => item.Validity));

Try this:
var results = NotSelectedList.Where(x => x.Valid);
foreach (var item in results)
SelectList.Add(item);
Although for performance reasons you may be better off doing something like this:
foreach (var item in NotSelectedList)
{
if (item.Valid)
SelectList.Add(item);
}

Related

How to get distinct values of each property independently

I have large yielded collection and I would like to get distinct values of each property independently:
IEnumerable<MyClass> collection = ...;
var prop1Values = collection.Select(i => i.Prop1).Distinct();
var prop2Values = collection.Select(i => i.Prop2).Distinct();
var prop3Values = collection.Select(i => i.Prop3).Distinct();
How to get it without enumerating the collection multiple times? Looking for most intuitive solution :)
You can try do it in a single foreach with a help of HashSet<T>s:
//TODO: put the right types for TypeOfProp1, TypeOfProp2, TypeOfProp3
var prop1Values = new HashSet<TypeOfProp1>();
var prop2Values = new HashSet<TypeOfProp2>();
var prop3Values = new HashSet<TypeOfProp3>();
foreach (var item in collection) {
prop1Values.Add(item.Prop1);
prop2Values.Add(item.Prop2);
prop3Values.Add(item.Prop3);
}

Linq replace column value with another value

Well, im doing a linq query to get a list of results with the same column, and then i need to replace that column value with a new one.
First Code:
var db = GetContext();
var result = from f in GetContext().ProjectStateHistories
where f.ProjectId.Equals(oldProjectId)
select f;
foreach (var item in result)
{
var projectStateHistoryUpdate = db.ProjectStateHistories.Find(item.Id);
projectStateHistoryUpdate.ProjectId = newProjectId;
db.Entry(projectStateHistoryUpdate).State = EntityState.Modified;
}
db.SaveChanges();
I searched for some answers, and i found that i can use Select, and make a new object (Linq replace null/empty value with another value)
Second Code:
var result = (from f in GetContext().ProjectStateHistories
where f.ProjectId.Equals(oldProjectId)
select f).Select(d=> new { Id = d.Id, EventName = d.EventName, LogUser = d.LogUser, ProjectId = newProjectId, TimeStamp = d.TimeStamp });
And even, Third Code:
var db = GetContext();
var result = (from f in db.ProjectStateHistories
where f.ProjectId.Equals(oldProjectId)
select f).Select(d=> new { ProjectId = newProjectId});
But only the First Code works.
I wanted to ask what i am doing wrong, since i think it is better to change the value with a query, instead of using a foreach.
See code below:
var db = GetContext();
(from f in db.ProjectStateHistories
where f.ProjectId.Equals(oldProjectId)
select f)
.ToList()
.ForEach(i => i.ProjectId = newProjectId);
db.SaveChanges();
Alternatively:
var db = GetContext();
db.ProjectStateHistories
.Where(f => f.ProjectId.Equals(oldProjectId))
.ToList()
.ForEach(f => f.ProjectId = newProjectId);
db.SaveChanges();
The shortest way I know of to replace your code is this:
var db = getcontext();
db.ProjectStateHistories
.Where(f => f.ProjectId.Equals(oldProjectId))
.ToList()
.ForEach(f => f.ProjectId = newProjectId);
db.SaveChanges();
Other answers can be found here
I've just had a thought that could help you, I am just free coding here!
If you just put the for each as part of the select, and then save your changes will that work?
foreach (var source in db.ProjectStateHistories.Where(x => x.ProjectId == oldProjectId))
{
source.ProjectId= newProjectId;
db.Entry(source).State = EntityState.Modified;
}
db.SaveChanges();
I think this is a more efficient way of doing it.
Also the .Select() method is only really useful if you need to Project to a view Model, it won't change the variables in the database, just show them in the newly declared object.
Thanks,
Phill

Nested Object from DataTable

I feel like I am way off track here. I have been banging my head against my keyboard and I do not feel like I am any closer to a solution. Guidance would be much appreciated.
Models.Content contains a SubContent property that is of type List<Models.Content>. The nesting could be infinite and should be recursive. I feel like this should be able to be done with a few lines of LINQ and while or something to that affect. I have created a mess.
private static List<Models.Content> GetAllContentFromDataSet(DataSet ds)
{
var content = new List<Models.Content>();
var contentList = (from DataRow row in ds.Tables[0].Rows
select new Models.Content
{
Id = Convert.ToInt32(row["Id"]),
ParentContentId = Convert.ToInt32(row["ParentContentId"]),
c3 = Convert.ToString(row["c3"]),
c4 = Convert.ToString(row["c4"]),
c5 = Convert.ToString(row["c5"])
}).ToList();
content.AddRange(NestContent(contentList));
return content;
}
private static IEnumerable<Models.Content> NestContent(List<Models.Content> content)
{
var toBeRemoved = new List<Models.Content>();
foreach (var c in content)
{
var parent = content.FirstOrDefault(p => p.Id == c.ParentContentId);
if (parent == null) continue;
parent.SubContent.Add(c);
toBeRemoved.Add(c);
}
foreach (var c in toBeRemoved)
{
content.Remove(c);
}
return content;
}
Here's an example of what I would do:
// Create a list of all items without children.
var things = table.AsEnumerable()
.Select(row => new Thing
{
Id = row.Field<int>("Id"),
ParentId = row.Field<int>("ParentId")
})
.ToList();
// Add children to each item.
things.ForEach(t1 => t1.Children = things.Where(t2 => t2.ParentId == t1.Id).ToList());
// Create a list of items that don't have a parent..
things = things.Where(t => t.ParentId == 0).ToList();
I agree, I think you could build your model hierarchy with fewer lines of code, thus, making your code easier to maintain and read. I'd actually do this in two steps...
Parsing the root "content" first (those with ParentContentId == null...I guess)...this can be done in one line of code with LINQ
Then iterate through all child content rows (those with a ParentContentId specified) and "attach" them to the parent content (if exists)
Let me know if you got the idea or if you need an example

LINQ - Assign a Value to Anonymous Type's Read Only Property

I would like to create an anonymous type from linq. Then change the value of a single property(status) manually and give the list to a repeater as data source. But doesn't let me do that as theay are read-only. Any suggestion?
var list = from c in db.Mesai
join s in db.MesaiTip on c.mesaiTipID equals s.ID
where c.iseAlimID == iseAlimID
select new
{
tarih = c.mesaiTarih,
mesaiTip = s.ad,
mesaiBaslangic = c.mesaiBaslangic,
mesaiBitis = c.mesaiBitis,
sure = c.sure,
condition = c.onaylandiMi,
status = c.status
};
foreach (var item in list)
{
if (item.condition==null)
{
item.status == "Not Confirmed";
}
}
rpCalisanMesai.DataSource = list.ToList();
rpCalisanMesai.DataBind();
Instead of trying to change the value after creating the list, just set the right value while creating the list.
var list = from c in db.Mesai
join s in db.MesaiTip on c.mesaiTipID equals s.ID
where c.iseAlimID == iseAlimID
select new
{
tarih = c.mesaiTarih,
mesaiTip = s.ad,
mesaiBaslangic = c.mesaiBaslangic,
mesaiBitis = c.mesaiBitis,
sure = c.sure,
condition = c.onaylandiMi,
status = c.onaylandiMi != null ? c.status : "Not Confirmed"
};
Also, if you could change the property, your problem would be executing the query twice: first in the foreach-loop, and then again by calling list.ToList() (which would create new instances of the anonymous type).
You cannot, anonymous type's properties are read-only.
You need to set it during object creation. See #Dominic answer for code sample.
You can. For instance:
var data = (from a in db.Mesai select new { ... status = new List<string>() .. }).ToList();
Next, compute your status:
foreach (var item in data) {
item.status.Add("My computed status");
}
And then on rendering:
foreach (var item data) {
Response.Write(item.status[0]);
}
EDIT: The list can even be intialized as per your requirement:
var data = (from a in db.Mesai select new { ... status = new List<string>(new
string[] { c.status }) .. }).ToList();
foreach (var item in data) {
item.status[0] = "My computed status";
}
EDIT2: Seems like you must initialize the list, preferably with e.g. c.rowid.ToString(), otherwise the optimizer assigns the same new List() to all items, thinking that this might be some game or something.

LinqToSQL - Effecient handling of objects - Retrieving first/single iobject

The last few weeks I have been working with LinqToSql, I love it and the community here is fantastic.
I created a query to find an Object in the Database and update the values, It seems to work fine, but the code doesn't look natural to me, I would imagine there is a better solution.
Please review the code below;
//Return a list of MyObject items
// irrelevant line, just to show what the objects are
List<MyObject> items = Factory.GetObjects();
foreach (var item in items)
{
var myObjects= from myobj in db.MyOjects
where myobj.id == item.Key
select myobj;
//Should ONLY find 1 object
//Below is the code I think we could optimize
if (myObjects.Count() == 1)
{
myObjects.First().propertyToChange1 = item.p1;
myObjects.First().propertyToChange2 = item.p2;
myObjects.First().dateAltered = DateTime.Now;
//Update DB
db.SubmitChanges();
}
}
A better solution is to use SingleOrDefault, like this:
var myObject = db.MyOjects.SingleOrDefault(myobj => myobj.id == item.Key);
if (myObject != null) {
myObject.propertyToChange1 = item.p1;
myObject.propertyToChange2 = item.p2;
myObject.dateAltered = DateTime.Now;
//Update DB
db.SubmitChanges();
}
you can also approach it with first or default in a regular query way
var myObjects= (from myobj in db.MyOjects
where myobj.id == item.Key
select myobj).FirstOrDefault();
if (myObjects != null)
{
myObjects.First().propertyToChange1 = item.p1;
myObjects.First().propertyToChange2 = item.p2;
myObjects.First().dateAltered = DateTime.Now;
//Update DB
db.SubmitChanges();
}

Categories