I have a Dictionary:
var dict = new Dictionary<int, string>();
With this values:
[0]: {[1, "Person1"]}
[1]: {[2, "Person2, Person3"]}
[2]: {[3, "Person4"]}
[3]: {[4, "Person5"]}
And when i use a "foreach" to get the values with "id" 2 i get as result "Person2, Person3".
foreach (var test in dict)
{
if (test.Key == 2)
System.Diagnostics.Debug.WriteLine(test.Value);
}
But when i use this LINQ line:
Person = dict.FirstOrDefault(q => q.Key == s.Person.ID).Value.ToString(),
I get this error:
Local sequence cannot be used in LINQ to SQL implementations of query
operators except the Contains operator.
I tried several things but nothing seems to work, so any ideas?
EDIT
I use this to show output on my page:
DataSelectionQuery = p => new
{
p.ID,
p.FirstName,
p.LastName,
TEST = dict.FirstOrDefault(q => q.Key == p.ID).Value.ToString(),
};
public Expression<Func<LinqClass, object>> DataSelectionQuery { get; set; }
And here is where it trows the error:
var results = query.Select(DataSelectionQuery).ToList();
You cannot use this kind of expressions inside Linq to SQL as they cannot be translated to SQL query
Use .ToList() at the end of your query, then use Linq to objects to complete your entity with values from Dictionary
For example when you have code like:
var result = from x in table
select new Entity
{
Id = x.Id,
Sth = x.Sth,
Person = dict.FirstOrDefault(q => q.Key == s.Person.ID).Value.ToString()
};
You need to change it to something like this:
var result = (from x in table
select new { x.Id, x.Sth, x.PersonId }) // LINQ To SQL part
.ToList() // get query results
.Select(x => new Entity
{
Id = x.Id,
Sth = x.Sth,
Person = dict.FirstOrDefault(q => q.Key == x.PersonId).Value.ToString()
}; // this part will be executed with Linq to objects
Please provide the full source code if you need more detailed help
Ok, so your "SelectionQuery" needs to be simple enough to translate into SQL query and should look like this:
DataSelectionQuery = p => new
{
p.ID,
p.FirstName,
p.LastName
};
And the other part should look like this:
var results = query.Select(DataSelectionQuery).ToList()
.Select(p => new
{
p.ID,
p.FirstName,
p.LastName,
TEST = dict.FirstOrDefault(q => q.Key == p.ID).Value.ToString()
});
Alernatively you can create your own class which will contain the Dictionary and will translate the ID into TEST on the getter action
This is how I solved the problem:
Person = string.Join(", ", PersonsQuery.Where(q => q.ID == s.ID).Select(q => q.PersonInformation))
Related
this not work
string[] DATE_Group = { "2020", "2021" }; //changing values
var query = _context.c10
.Where(u => DATE_Group.Any(s => u.ON_DATE.Contains(s)))
.ToList()
.Select(u => new
{
User_NumberID = u.User_NumberID.ToString(),
}).ToList();
I use this u.ON_DATE.Contains("2020") and work but not list or array only one value
in sql SELECT * from C10 where ON_DATE like '%2020%' or ON_DATE like '%2021%'
and in ON_DATE column content like this 1-3-2023 1-1-2021 5-1-2020
this error when used
enter image description here
Use this below code for your linq where statement.
var myVar=context.Students.where(x=>x.Name.Contains("John")).SingleOrDefault();
I think this is a better way to get the data:
var from = new DateTime(2020,1,1);
var to = new DateTime(2022,1,1);
var query = _context.c10
.Where(u => u.ON_DATE > from && u.ON_DATE < to )
...
EF Core cannot use Any with local collections (with small excpetion), only Contains is supported.
I would suggest to use function FilterByItems. And use in query:
string[] DATE_Group = { "2020", "2021" }; //changing values
var query = _context.c10
.FilterByItems(DATE_Group, (u, s) => u.ON_DATE.Contains(s), true)
.Select(u => new
{
User_NumberID = u.User_NumberID.ToString()
})
.ToList();
I'm trying to get a list of people who have at least one family member associated in the database.
FamilyMembers is a related table, tied by a one-to-many foreign key.
[one] People.PersonId --> [0 or more] FamilyMembers.PersonId
I tried doing this, but Count() doesn't seem to work like I thought it would.
I get results containing both 0 and more FamilyMembers.
public IEnumerable<Person> GetPeopleWithFamilyMembers()
{
IQueryable<Person> query = Context.Persons;
query = query.OrderBy(x => x.FamilyMembers.Count());
query = query.Where(x => x.FamilyMembers.Count() > 0);
// Execute query and return result:
return query.Select(x => x);
}
I'm really not sure what to do here :-/
I struggled for a good bit on a elegant solution to this without using expanded query form.
The only way I could achieve this in SQL was using a Group By and a Join, but I have no idea if I translated it to LINQ correctly. Please feel free to point out my mistakes.
var query = Persons
.Join(FamilyMembers,
p => p.Id,
f => f.Id,
(p,f) => new { Person = p, FamilyMembers = f }
)
.GroupBy(g => g.FamilyMembers)
.Where(w => w.FamilyMembers.Count() > 0);
.Select(x => new {
Person = x.Person,
FamilyMembers = x.Count(y => y.FamilyMembers)
}
);
I have an object that has a list of another object in it. i.e Object1 contains List<Object2>.
Assuming this is the definition of object 2:
public class Object2
{
string code,
string name,
decimal amount
}
I want to be a able to make a list2 from the list whose value will contain what something similar to what a select name, code, sum(amount) group by code kinda statement could have given me
this is what i did but it didnt contain what i needed on passing through.
var newlist = obj2List.GroupBy(x => x.code)
.Select(g => new { Amount = g.Sum(x => x.amount) });
I want code and name in the new list just like the sql statement above.
You're almost there:
var newlist = obj2List.GroupBy(x => x.code)
.Select(g => new
{
Code = g.First().code,
Name = g.First().name,
Amount = g.Sum(x => x.amount)
});
This groups the items by code and creates an anonymous object for each group, taking the code and name of first item of the group. (I assume that all items with the same code also have the same name.)
If you are grouping by code and not by name you'd have to choose something for name from the list, perhaps with First() or Last() or something.
var newlist = obj2List.GroupBy(x => x.code).Select(g => new {
Code = g.Key,
Name = g.First().name,
Amount = g.Sum(x => x.amount)
});
var query = Object1.Obj2List
.GroupBy(obj2 => obj2.code)
.Select(g => new {
Names = string.Join(",", g.Select(obj2.name)),
Code = g.Key,
Amount = g.Sum(obj2 => obj2.Amount)
});
Since you group by code only you need to aggregate the name also in some way. I have used string.Join to create a string like "Name1,Name2,Name3" for each code-group.
Now you could consume the query for example with a foreach:
foreach(var x in query)
{
Console.WriteLine("Code: {0} Names: {1} Amount: {2}"
, x.Code, x.Names, x.Amount);
}
Instead of using the LINQ Extension Methods .GroupBy() and .Select() you could also use a pure LINQ statement which is way easier to read if you come from a SQL Background.
var ls = new List<Object2>();
var newLs = from obj in ls
group obj by obj.code into codeGroup
select new { code = codeGroup.Key, amount = codeGroup.Sum(s => s.amount) };
How to Put the following query result into a List
var result = from c in sb.Swithches_SW_PanalComponents
select new { c.ID,c.SW_PanalComponents.ComponentsName,c.ComponentValue };
FINAL EDIT
Based on your last comment, this is all you ever needed
List<Swithches_SW_PanalComponents> result =
sb.Swithches_SW_PanalComponents.ToList();
which of course is identical to
var result = sb.Swithches_SW_PanalComponents.ToList();
EDIT
Based on your comments, I think this is what you want:
List<SW_PanalComponents> result = sb.Swithches_SW_PanalComponents
.Select(c => new SW_PanalComponents { /* initialize your fields */ })
.ToList();
END EDIT
The ToList method is what you want. But consider using dot notation. For simple queries like this, it's much cleaner and trimmer.
var result = sb.Swithches_SW_PanalComponents
.Select(c => new { c.ID, c.SW_PanalComponents.ComponentsName, c.ComponentValue })
.ToList();
Also note that, if you're just trying to execute your query immediately, and only need to enumerate over it, you can also call AsEnumerable()
var result = sb.Swithches_SW_PanalComponents
.Select(c => new { c.ID, c.SW_PanalComponents.ComponentsName, c.ComponentValue })
.AsEnumerable();
The advantage here is that result is a less specific type—IEnumerablt<T>.
Like this:
var result =(from c in sb.Swithches_SW_PanalComponents
select new
{ c.ID,
c.SW_PanalComponents.ComponentsName,
c.ComponentValue
}).ToList();
That what i came with finally:
List<Swithches_SW_PanalComponents> MyList = new List<Swithches_SW_PanalComponents>();
var Result = from all in sb.Swithches_SW_PanalComponents
select all
;
MyList.AddRange(Result.ToList<Swithches_SW_PanalComponents>());
I currently have 3 tables:
News
ID | Title
Tag
ID | Name
TaggedContent
ContentID | TagID
And I have two context objects: NewsEntities and TagsEntities
I want to select all tags used by News, in my application I have:
static void Main(string[] args)
{
IEnumerable<dynamic> something = null;
IEnumerable<News.Data.News> news = null;
IEnumerable<Tags.Data.Tag> tags = null;
IEnumerable<TaggedContent> tagged = null;
using (var db = new NewsEntities())
{
news = db.News.ToList(); // 1 select
}
using (var db = new TagsEntities())
{
something = news.Join(db.TaggedContents.ToList(),
n => n.ID,
tc => tc.ContentID,
(n, tc) => new { tc.TagID }); // 1 select
something = something.Join(db.Tags.ToList(),
tid => tid.TagID,
t => t.ID,
(tid, t) => t); // 1 select
}
var result = something;
}
I am currently generating 3 selects. How can I reduce it to 2? Or if possible I would like to reduce to 1 without merging the entities.
Since you're joining entities from different contexts, you can't get away with fewer than 2 selects.
Your join is a simple identity check, so you could do this:
var ids = db.News.Select(x => x.ID).ToList();
You now have a local copy of all of the IDs in the news table -- the first select. Then change your first 'something' to:
something = db.TaggedContents
.Where(x => ids.Contains(x.ContentID))
.Select(x => new { x.TagID });
This second statement won't in itself generate a select because of deferred execution. You can now remove the ToList() in the third statement:
something = something.Join(db.Tags,
tid => tid.TagID,
t => t.ID,
(tid, t) => t);
And when you finally enumerate over something, you'll have your second select.
Using DataLoadOptions class passed in the creation of your DataContext.
DataLoadOptions options = new DataLoadOptions();
db.LoadOptions = options;
options.LoadWith((News n) => n.Tags);
So do for the remaining of the data to join.