entity objects where in list - c#

i followed this tutorial for setting up an upload/download to/from sql database.
http://dotnetawesome.blogspot.co.uk/2013/11/how-to-upload-and-download-files-tofrom.html
It works just fine. But i want to modify the populate method so that it will only populate files where the fileid exists within a list that i've stored in session state.
The problem is i've looked around and i can't make any sense of the lambda expressions or work out how to do this.
Basically, i keep a list of the fileIDs in the session, (which is renewed on first page load) so it will only show the files uploaded for that form submission. (it's a claim form)
using (Portal_Entities dc = new Portal_Entities()) {
List<WEBSITE_ATTACHMENTS> allFiles = dc.WEBSITE_ATTACHMENTS.ToList()
rptAttachments.DataSource = allFiles;
rptAttachments.DataBind();
}
I'm guessing i need to put a .Where or .Select on the .ToList here, but i'm not sure.
Like i need a sql type statement where field in ('value','value') where there values come from the list in the session.
Can anyone help?

You could try this one:
// Get the list of ints called fileIDs that you have stored in session.
List<int> ids = (List<int>)Session["fileIDs"];
// Declare an enumeration in which only the WEBSITE_ATTACHMENTS
// with an in contained in ids, will be contained.
List<WEBSITE_ATTACHMENTS> allFiles = dc.WEBSITE_ATTACHMENTS
.Where(x=>ids.Contains(x.fileId));

Related

Creating a linq condition using a list

I have a method which used for getting a list from the database.
public List<SelectedCustomers> GetCustomers(List<int> customerNumbers)
{
var customers=_context.Customers.Where(?).Select(i=> new SelectedCustomers() {}).ToList()
}
I want to retrieve information from the database of customers whose customer number is given by the user. There are about one hundred thousand customers in the customer list in the database. I do not want the method to take the whole list and search it every time it is called, it takes too much effort. However, I don't know how to use a list in where ().
In summary, instead of pulling out all the list I want and searching the values requested by the user in the list, I want to go to the database with the list that comes directly from the user and give me the information of these customers.
I hope I could explain. Thank you for your help.
Try this:
var customers = _context.Customers.Where(c => customerNumber.Contains(c.CustomerId)).Select(i => new SelectedCustomers() { }).ToList()
Try something like (not tested)
public List<SelectedCustomers> GetCustomers(List<int> customerNumbers)
{
var customers=_context.Customers.Where(x =customerNumbers.Contains(x.customerNumber)
.Select(i=> new SelectedCustomers() {}).ToList()
}
This is the equivalent of the SQL IN ()

Select Numeric Values From String Linq to Entities

I have records that have a string property called Project. The values these normally have are like A-A-40019-0 but in reality they could be anything.
I need to be able to extract the numeric values from the Project project property so that I can then try and cast it to a ulong so that it can be sorted by.
I'm trying the following code to select the number values from the Project property.
return jobs.Select(x => new JobViewModel
{
Sequence = x.Project.Where(y => char.IsDigit(y)).ToString()
});
When I try this I get the following error
DbExpressionBinding requires an input expression with a collection
ResultType.
I need to use Linq to Entities as I can't afford to load all records into memory.
I'm using SQL Server.
You don't say which DB you are using but I did find this for SQL Server. https://www.mytecbits.com/microsoft/sql-server/extract-numbers-from-string#:~:text=%20Extract%20Numbers%20From%20String%20In%20SQL%20Server,you%20want%20to%20split%20this%20delimited...%20More%20
Hopefully similar technique can be used for the DB you are using.
You could make a view with a column calling that function added on the end and then you can sort it.
or purely in C# which I haven't tried:
Convert.ToInt32(new string(y.project.Where(c => Char.IsDigit(c)).ToArray())

Linq fails to select from large data set

I am trying to select a result set in to a list of object type.
var temp = res.Select(a => new ContentAudit {
locale = a.locale,
product_code = a.product_code, product_name = a.product_name,
image = a.image, product_short_description = a.product_short_description,
product_long_description = a.product_long_description,
items = a.items,
service_articles = GetServiceArticleCount(a.product_id).ToString(),
is_deleted = a.is_deleted, views = a.views,
placed_in_cart = GetPlacedInCartCount(a.product_id).ToString(),
ordered = GetOrderedCount(a.product_id).ToString(),
Importance = GetImportance(a.product_id),
operation = (a.product_id.ToString()) }
).ToList();
I am selecting from 'res' variable which is the result set selected from the database. Which has aroun 65000 records. So because of that the line of code above dosent work and the server get stucked. Is there anyother way i can achieve this? Thank you
There are many problems with this query.
1st You are trying to select 65000 records from DB and use .ToList()
It will iterate all objects.
You should use IEnumerable (or IQueryable), and use lazy loading.
If you do not need all of this objects try to add .Where() statement to limit number of entities.
2nd in query You are using methods wich are trying to make even more request to db. Do You realy need all this data? If yes make sure that everything is using lazy loading. Do not iterate it all in one time!
I can see two solutions. If You don't need all this data, take only data You need from db and limit number of retrived entitiies as much as its posible.
If you realy need all this data, try to use lazy loading, and add pagination (.take() and .skip() methods) to limit number of entites retrived in one call.

Check or nickname already exists in List<User>

I am creating an ASP website with a possibility to register.
The nickname that visitors choose to register has to be unique.
Everytime when an user registers, I select all users from the database, and then I am using a foreach loop to check or username already exists:
private List<User> listExistingUsers;
listExistingUsers = Database.GetUsers();
foreach (User u in listExistingUsers)
{
if (u.Nickname == txtNickname.text)
{
Error = "Username already in use.";
}
}
But the code above doesn't work properly. It doesn't check all the items in the list which are read from the database. So it is possible to have users with the same usernames, which I don't want.
What can I do to solve this problem? I read about LINQ, but I think that this is the wrong way of checking usernames with List<> in my opinion. I think this username-check must be done in another way.
Can you experts help me? I could also do this check with a SQL-query, but I would like to do it in c#.
Instead of returning ALL users from DB, pass username to Query/stored procedure and let backend do the check, and then return back just a status flag 1/0 - exists/doesn't.
if (Database.GetUsers().Select(x => x.Nickname).Contains(txtNickname.Text)) should do what you want.
I've condensed everything into a single line so I'll give a quick explanation; First I use your Database.GetUsers() method to retrieve the users, then I use select to project the Nickname since that's what we're comparing. If that were to execute on it's own it would result in an IEnumerable<string> with all of the Nicknames. From there I use contains to see if that list contains the nickname that (I'm assuming) has been entered in the UI.
You can use Contains operator in order tocheck
listExistingUsers.Select(x => x.Nickname).Contains(txtNickname.text);
link : http://msdn.microsoft.com/fr-fr/library/bhkz42b3%28v=vs.80%29.aspx
Remark : You can use Any or count (very expensive last solution)
Use Any operator. It checks whether any element of a sequence satisfies some condition. In your case condition is user nickname equals to text in textBox:
if (Database.GetUsers().Any(u => u.Nickname == txtNickname.Text))
Error = "Username already in use.";
BTW if you change GetUsers to return IQueryable<User> then check will occur on server side.
Do get a list of NickNames once
var nickNames = new List<string>();
for(int i=0;i<listExistingUsers.Count;i++)
{
nickNames.Add(listExistingUsers.NickName);
}
Then u can simply use
if(nickNames.Contains(txtNickname.text))
{
Error = "Username already in use.";
}
1) Have you verified that Database.GetUsers() is actually returning the full list, with no SQL issues?
2) Do you need it to be case-insensitive?
3) You can use the LINQ to do the query like this:
if (listExistingUsers.Any(u => string.Equals(u, txtNickname.Text, StringComparison.CurrentCultureIgnoreCase)))
{
// Process error
}
If Database.GetUsers() return all the users from database, so do not use it! Imagine if you have already 1000 of users, for each new user it will load all the users, and you will have performance issues.
Instead, create a new method that search your database and return only one result, case it exists.
Something like :
private bool Database.UserExists(txtNickname.text) {
//Your query to database with a where statment looking for the nickname. It could be a LINQ query, or any other way you use in your system.
//If it brings 1 result, it has to return true.
}
I think the most tricky part of your task is to fill the database Correctly.
Particularly:
Cut off trailing and ending spaces
Decide if the user names should becase sensitive
Make sure that when creating a new user name you do not have the nick already
About Loading users and checking:
As mentioned above LINQ is the most effective a C# like checking for duplicates
( if (Database.GetUsers().Select(x => x.Nickname).Contains(txtNickname.Text)))
I am more used to writing SQL statements than using LINQ. If you've got lots of users SQL will read only the selected ones but I don't know if the LINQ statement above pulls all users into the memory pool or just the one(s) with the same nickname.

Generic questions about best practice while developing in sharepoint

I have a few generic questions about what are the best practices for SharePoint(2010).
I am currently implementing a feature that requires me to fetch information from a list. I am not quite sure on how to manage these information. I created a class that helps me manage theses information (User.cs). I have a getter in the class that currently searches for a value in a specific list. How should i handle the value ? Should i keep it in a member and refresh only when its subject to changes or should i refresh the value from the list each time i get it ?
private void doesUserHasActivities(){
using(SPSite site = new SPSite("http://vmsharepoint2010/")){
using(SPWeb web = site.openWeb("http://vmsharepoint2010/")){
SPList list = web.list["Users"];
SPListItem user;
/*Information values is refresh each time its accessed, is this bad ?*/
for(int i=0; i < list.items.length; i++){
user = list.item[i];
string accName = user["Acc_Name"];
if(accName == this.providedAccountname){//providedAccountname from a TextBox
//found the user i wanted into the list
//look if the list has data
bool hasActivities = user["Activities"] != null;
}
}
}
}
}
Also, is there other ways to access specific data, in this case the activities list without looping through each rows trying to match the correct user and then looking up the values in the activities list ?
Can i store the row itself as a member for my meta data ? Will my reference still point to the row of the user list i want to if another user is added ?
You'll need to learn CAML and perform a CAML query.
Create an SPQuery object. Set it's Query property to be what you need it to be, then use list.getItems(SPQuery query) to get just the items that match your query.
You can figure out the CAML for it yourself; you'll need to learn it if you want to deal with SharePoint code at all. There is lots of information on basic syntax, and tools for helping auto-generate it based on more user friendly syntax.
The items won't update dynamically when items are added to the list or updated in the list; you will need to re-run the query.

Categories

Resources