How to get all the values from an SQL Query C# - 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"]
};
}
}

Related

C# - How to filter list using enum

I have 2 a classes:
public enum ArticleType
{
News = 1;
SpecialOffer = 2;
Service = 3;
}
public ArticleApiDto
{
public int Id;
public ArticleType Type;
}
Now i have method for getting data from db, something like:
public List<ArticleApiDto> GetAll(List<ArticleType> types)
{
var res = new List<ArticleApiDto>();
res = context.articles.ToList();
//do stuff
}
Now I would like to filter out Articles from res whose type is specified in types from parameter of method.
Problem 1: I actually cant use Contains because ArticleType is enum
Problem 2: List<ArticleType> is because sometimes i want to pass only one type but sometimes two or three. At the moment i cant figure out better better solution.
Can someone help me with this please I was searching for whole noone but cant figure out
To be able to pass more than one type you can do it like:
Make your enum to be Flags (note that values now can't be 1,2,3,4 and should be 1,2,4,8,16,...:
[Flags]
public enum ArticleType
{
News = 1;
SpecialOffer = 2;
Service = 4;
}
Now you add up what you want to filter with |:
filter = ArtickeType.News | ArticleType.Service;
var result = res.Where(x => filter & x.Type != 0).ToList();
or:
filter = ArtickeType.News | ArticleType.Service | ArticleType.SpecialOffer;
var result = res.Where(x => filter.HasFlag(x.Type)).ToList();
To do it with your current enum:
public enum ArticleType
{
News = 1;
SpecialOffer = 2;
Service = 3;
}
var filter = new List<ArticleType> { ArticleType.Service, ArticleType.News};
var result = res.Where(x => filter.Contains(x.Type)).ToList();
This code work with me, I use Linq with contains it may solve your problem.
public static List<ArticleApiDto> GetAll(List<ArticleType> types)
{
var res = new List<ArticleApiDto>();
List<ArticleApiDto> articles = new List<ArticleApiDto>
{
new ArticleApiDto{Id = 1, Type = ArticleType.News },
new ArticleApiDto{Id = 2, Type = ArticleType.SpecialOffer },
};
var newArticales = articles.Where(i =>
{
return types.Contains(i.Type);
}).ToList();
return newArticales;
}

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;
}

Querying the id of an entity using linq

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)

C#. Set a member object value using reflection

I need your help with the following code below. Basically I have a class called "Job" which has some public fields. I'm passing to my method "ApplyFilter" two parameters "job_in" and "job_filters". First parameter contains actual data, and the second one has instructions (if any). I need to iterate through "job_in" object, read it's data, apply any instructions by reading "job_filters", modify data (if needed) and return it in a new "job_out" object. Everything works fine till i need to store my data in "job_out" object:
public class Job
{
public string job_id = "";
public string description = "";
public string address = "";
public string details = "";
}
...
private Job ApplyFilters(Job job_in, Job job_filters)
{
Type type = typeof(Job);
Job job_out = new Job();
FieldInfo[] fields = type.GetFields();
// iterate through all fields of Job class
for (int i = 0; i < fields.Length; i++)
{
List<string> filterslist = new List<string>();
string filters = (string)fields[i].GetValue(job_filters);
// if job_filters contaisn magic word "$" for the field, then do something with a field, otherwise just copy it to job_out object
if (filters.Contains("$"))
{
filters = filters.Substring(filters.IndexOf("$") + 1, filters.Length - filters.IndexOf("$") - 1);
// MessageBox.Show(filters);
// do sothing useful...
}
else
{
// this is my current field value
var str_value = fields[i].GetValue(job_in);
// this is my current filed name
var field_name = fields[i].Name;
// I got stuck here :(
// I need to save (copy) data "str_value" from job_in.field_name to job_out.field_name
// HELP!!!
}
}
return job_out;
}
Please help. I've seen a few samples by using properties, but i'm pretty sure it is possible to do the same with fields as well. Thanks!
Try this
public static void MapAllFields(object source, object dst)
{
System.Reflection.FieldInfo[] ps = source.GetType().GetFields();
foreach (var item in ps)
{
var o = item.GetValue(source);
var p = dst.GetType().GetField(item.Name);
if (p != null)
{
Type t = Nullable.GetUnderlyingType(p.FieldType) ?? p.FieldType;
object safeValue = (o == null) ? null : Convert.ChangeType(o, t);
p.SetValue(dst, safeValue);
}
}
}
fields[i].SetValue(job_out, str_value);

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();

Categories