Querying the id of an entity using linq - c#

In the following method I am trying to fetch the Username by passing the id value where the ids passed as parameter can be multiple values as in csv's (eg: 1,2) and are returned to the calling function as IEnumerable.
Code Follows as below :
[NonAction]
public static IEnumerable<UserProfile> SearchCMSAdmins(string s)
{
//var searchResults = Entities.UserProfiles.Where(item =>item.UserName.Contains(s));
//return searchResults;
string[] ids = s.Split(',');
IEnumerable<UserProfile> results = null;
IList<UserProfile> user = new List<UserProfile>();
for (int i = 0; i < ids.Length; i++)
{
int id = Convert.ToInt32(ids[i].ToString());
var entity = Entities.UserProfiles.Where(item => item.UserId);
//user.Add(entity);
results = results.Concat(entity);
}
return results;
}
Any help is appreciated.

Try using Contains:
var results = Entities.UserProfiles.Where(item => ids.Contains(item.UserId));
http://msdn.microsoft.com/en-us/library/ms132407.aspx

You can get the id array to be of int type, You can either use int.TryParse or Convert.ToInt32 like:
int[] ids = s.Split(',').Select(r=> Convert.ToInt32(r)).ToArray();
Later you can modify your LINQ query as:
IList<UserProfile> user = Entities.UserProfiles
.Where(item=> ids.Contains(item)).ToList();
This would be like Select * from table where ID in (1,2,3) see Creating IN Queries With Linq to SQL for idea

[NonAction]
public static IEnumerable<UserProfile> SearchCMSAdmins(string s)
{
string[] ids = s.Split(',');
foreach (string idAsString in ids)
{
int id = Convert.ToInt32(idAsString);
var entity = Entities.UserProfiles.Where(item => item.UserId == id);
yield return entity;
}
}
should do it (there should be some validation code too in case the id is not an int or the entity is null)

Related

How to get all the values from an SQL Query C#

I have used String Builder to generate a RAW SQL QUERY in C#.
List<string> columns = new List<string>();
columns.Add("id");
columns.Add("Temp");
StringBuilder SqlStatement = new StringBuilder();
SqlStatement.Append("Select ");
for (int i = 0; i < columns.Count; i++)
{
if (i == columns.Count - 1)
{
SqlStatement.Append(columns[i]);
}
else
{
SqlStatement.Append(columns[i]);
SqlStatement.Append(",");
}
}
SqlStatement.Append(" FROM graph_update");
var ctx = new graphDBContext();
var result = ctx.Database.SqlQuery<graphDBContext>(SqlStatement.ToString()).ToList();
This translates into SELECT id,Temp FROM graph_update
And the result gives me
id = 1, temp = 20
id = 2 temp = 30
How do I get all these values????
I'm too use to:
foreach(var item in result)
{
item.id = id;
item.temp = temp;
}
But it won't let me.
EDIT:
Sorry but I'm not sure what you mean. Here is my debugger
Try to use foreach like this if theres no error return
foreach(var v in result)
{
String v0 = v[0].ToString();
String v1 = v[1].ToString();
}
Assuming you have EF > 6, then the ctx.Database.SqlQuery, according to the method documentation:
Creates a raw SQL query that will return elements of the given generic type.
The type can be any type that has properties that match the names of the columns returned from the query, or can be a simple primitive type. The type does not have to be an entity type. The results of this query are never tracked by the context even if the type of object returned is an entity type.
With that in mind you can do something like this:
public class GraphUpdateResult
{
public int Id {get; set;}
public decimal Temp {get; set;}
}
Then in your current method:
var result = ctx.Database.SqlQuery<GraphUpdateResult>SqlStatement.ToString()).ToList();
foreach (var graphResult in result)
{
Console.WriteLine(graphResult.Id);
Console.WriteLine(graphResult.Temp);
}
You can add more columns to the GraphUpdateResult class for EF to bind to, even if in some queries you don't specify them in the select statement.
I hope this helps.
foreach(var item in result)
{
var id = item.id;
var temp = item.temp;
}
in your code above, you are trying to assign the values to the item, instead of retrieving.
You can use a ORM-Mapper like
https://stormy.codeplex.com/SourceControl/latest#Stormy.cs
It is a very light Mapper and you can look how it works.
It maps the reader Data to the Object data:
public class CatMapper : ISelectable<Cat>
{
public Cat ApplySelect(IDataReader reader)
{
return new Cat()
{
Name = reader["name"].ToString(),
Weight = (float)reader["weight"]
};
}
}

C# Mongo Query In not returning result

I'm having issue with getting back a result when using the Mongo In query. When I've tested the same query in native mongo, it's bringing back the correct result. Im trying to bring back all the ids that match in the temp array.
var temp = new BsonValue [collection.Count()];
for (int i = 0; i < collection.Count(); i++)
{
temp[i] = collection[i].ID;
}
var query = Query.In("ID", temp);
var collection2 = db.GetCollection<TXT>("TXT").Find(query).ToList();
What version of MongoDb's C# driver are you using? It looks like you might be using a deprecated version of the driver.
Here is an example of how we use to use the .In filter in version 2.0.1.27:
var filter = Builders<INVENTTXT>.Filter.In(item => item.ITEMID, temp);
var result = await db.GetCollection<INVENTTXT>("INVENTTXT")
.Find(filter)
.ToListAsync()
.Result;
In the legacy driver, assuming that your INVENTTXT looks something like this:
class INVENTTXT
{
[BsonId]
public ObjectId _id { get; set; }
public String ITEMID { get; set; }
}
Then this works for me to pull the values back:
public static void GetWhereIn()
{
var collection = new List<INVENTTXT>()
{
new INVENTTXT {ITEMID = "52719635"}
};
var temp = new BsonValue[collection.Count()];
for (int i = 0; i < collection.Count(); i++)
{
temp[i] = collection[i].ITEMID;
}
var query = Query.In("ITEMID", collection.Select(c => BsonValue.Create(c.ITEMID)));
var collection2 = db.GetCollection<INVENTTXT>("INVENTTXT").Find(query).ToList();
var count = collection2.Count;
}

The query results cannot be enumerated more than once

Consider the following methods. I am getting exception as asked , while repeater binding.
Bindrepeater:
private void BindRepeater()
{
var idx = ListingPager.CurrentIndex;
int itemCount;
var keyword = Keywords.Text.Trim();
var location = Area.Text.Trim();
var list = _listing.GetBusinessListings(location, keyword, idx, out itemCount);
ListingPager.ItemCount = itemCount;
BusinessListingsRepeater.DataSource = list.ToList(); // exception here
BusinessListingsRepeater.DataBind();
}
GetBusinessListings:
public IEnumerable<Listing> GetBusinessListings(string location, string keyword, int index, out int itemcount)
{
var skip = GetItemsToSkip(index);
var result = CompiledQueries.GetActiveListings(Context);
if (!string.IsNullOrEmpty(location))
{
result= result.Where(c => c.Address.Contains(location));
}
if (!string.IsNullOrEmpty(keyword))
{
result = result.Where(c => c.RelatedKeywords.Contains(keyword) || c.Description.Contains(keyword));
}
var list = result;
itemcount = list.Count();
return result.Skip(skip).Take(10);
}
GetActiveListings :
/// <summary>
/// Returns user specific listing
/// </summary>
public static readonly Func<DataContext, IQueryable<Listing>> GetActiveListings =
CompiledQuery.Compile((DataContext db)
=> from l in db.GetTable<Listing>()
where l.IsActive
select l);
When you assign itemcount you are executing the query the first time. Why do you need this?
My suggestion would be not to retrieve the item count there and just
return result.Skip(skip).Take(10).ToList();
Basically you can't have both, fetch only the results you need and retrieve the total count in one query. You could use two seperate querys though.
You may want to persist your results as a collection, not an IQueryable.
var list = result.ToArray();
itemcount = list.Length;
return list.Skip(skip).Take(10);
The above code may not be correct for paging. You likely will have to run the query twice.

remove list-items with Linq when List.property = myValue

I have the following code:
List<ProductGroupProductData> productGroupProductDataList = FillMyList();
string[] excludeProductIDs = { "871236", "283462", "897264" };
int count = productGroupProductDataList.Count;
for (int removeItemIndex = 0; removeItemIndex < count; removeItemIndex++)
{
if (excludeProductIDs.Contains(productGroupProductDataList[removeItemIndex].ProductId))
{
productGroupProductDataList.RemoveAt(removeItemIndex);
count--;
}
}
Now i want to do the same with linq. Is there any way for this?
The second thing would be, to edit each List-Item property with linq.
you could use RemoveAll.
Example:
//create a list of 5 products with ids from 1 to 5
List<Product> products = Enumerable.Range(1,5)
.Select(c => new Product(c, c.ToString()))
.ToList();
//remove products 1, 2, 3
products.RemoveAll(p => p.id <=3);
where
// our product class
public sealed class Product {
public int id {get;private set;}
public string name {get; private set;}
public Product(int id, string name)
{
this.id=id;
this.name=name;
}
}
Firstly corrected version of your current code that won't skip entries
List<ProductGroupProductData> productGroupProductDataList = FillMyList();
string[] excludeProductIDs = { "871236", "283462", "897264" };
int count = productGroupProductDataList.Count;
for (int removeItemIndex = 0; removeItemIndex < count; removeItemIndex++)
{
while (removeItemIndex < count && excludeProductIDs.Contains(productGroupProductDataList[removeItemIndex].ProductId)) {
productGroupProductDataList.RemoveAt(removeItemIndex);
count--;
}
}
}
This linq code would do the job.
List<ProductGroupProductData> productGroupProductDataList = FillMyList();
string[] excludeProductIDs = { "871236", "283462", "897264" };
productGroupProductDataList=productGroupProductDataList.Where(x=>!excludedProductIDs.Contains(x.ProductId)).ToList();
Alternatively using paolo's answer of remove all the last line would be would be
productGroupProductDataList.RemoveAll(p=>excludedProductIDs.Contains(p=>p.ProductId));
What you mean by "The second thing would be, to edit each List-Item property with linq."?
As per your comment here's a version that creates a set that excludes the elements rather than removing them from the original list.
var newSet = from p in productGroupProductDataList
where !excludeProductIDs.Contains(p.ProductId))
select p;
The type of newSet is IEnumerable if you need (I)List you can easily get that:
var newList = newSet.ToList();

Entity Random Select from DB C# MVC

Try to find the solution but i cant.
So problem is next one. I have the EDM model of database. I have a class with functions to get data from DB.
Like this:
public IQueryable<photos> FindUserPhotos(string userlogin)
{
return from m in db.photos
where m.userlogin == userlogin
select m;
}
How to get the Random 10 lines from DB?
I always use this method for get custom entity OrderBy(x => Guid.NewGuid())
public photos Find10RandomUserPhotos(string userlogin)
{
return db.photos.Where(x => x.userlogin == userlogin).OrderBy(x => Guid.NewGuid()).Take(10).ToList();
}
Following Random row from Linq to Sql
public photos FindRandomUserPhoto(string userlogin)
{
var qry = FindUserPhotos(userlogin);
int count = qry.Count();
int index = new Random().Next(count);
return qry.Skip(index).FirstOrDefault();
}
public Array<photos> Find10RandomUserPhotos(string userlogin)
{
var result = New Array<photos>;
for (i = 0; i < 10; i++) {
result.add(FindRandomUserPhoto(userlogin));
}
return result
}

Categories