C# Dictionary LINQ - linq

I have a class that returns all items in a database table (Code below). I also have a dictionary that contains key,value pair. Before I return the data from my function, can I look inside the dictionary and return the value that's associated with the key from my linq?
public IEnumerable<Code> Return_All_Codes()
{
return _db.Codes.ToList();
//can the above list look inside my dictionary below and return Administrative when it find the number 1 for my code type?
}
public Dictionary<int, string> GetCodeTypes()
{
var dict = new Dictionary<int, string>();
dict.Add(1, "Administrative");
dict.Add(2, "Regular");
return dict;
}
Can the above list look inside my dictionary and return Administrative when it finds the number 1 for my code type? Kind of an IF statement inside my LINQ? If 1 then Administrative, else Regular.

You can do this mapping via:
var dict = GetCodeTypes();
return _db.Codes.AsEnumerable().Select(code => dict[code.cType]).ToList();
However, I'd recommend storing the dictionary in your class to prevent creating it each time, especially if this is called many times.

Related

what is a projection in LINQ, as in .Select()

I typically do mobile app development, which doesn't always have .Select. However, I've seen this used a bit, but I don't really know what it does or how it's doing whatever it does. It is anything like
from a in list select a // a.Property // new Thing { a.Property}
I'm asking because when I've seen code using .Select(), I was a bit confused by what it was doing.
.Select() is from method syntax for LINQ, select in your code from a in list select a is for query syntax. Both are same, query syntax compiles into method syntax.
You may see: Query Syntax and Method Syntax in LINQ (C#)
Projection:
Projection Operations - MSDN
Projection refers to the operation of transforming an object into a
new form that often consists only of those properties that will be
subsequently used. By using projection, you can construct a new type
that is built from each object. You can project a property and perform
a mathematical function on it. You can also project the original
object without changing it.
You may also see:
LINQ Projection
The process of transforming the results of a query is called
projection. You can project the results of a query after any filters
have been applied to change the type of the collection that is
returned.
Example from MSDN
List<string> words = new List<string>() { "an", "apple", "a", "day" };
var query = from word in words
select word.Substring(0, 1);
In the above example only first character from each string instance is selected / projected.
You can also select some fields from your collection and create an anonymous type or an instance of existing class, that process is called projection.
from a in list select new { ID = a.Id}
In the above code field Id is projected into an anonymous type ignoring other fields. Consider that your list has an object of type MyClass defined like:
class MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
Now you can project the Id and Name to an anonymous type like:
Query Syntax:
var result = from a in list
select new
{
ID = a.Id,
Name = a.Name,
};
Method Syntax
var result = list.Select(r => new { ID = r.Id, Name = r.Name });
You can also project result to a new class. Consider you have a class like:
class TemporaryHolderClass
{
public int Id { get; set; }
public string Name { get; set; }
}
Then you can do:
Query Syntax:
var result = from a in list
select new TemporaryHolderClass
{
Id = a.Id,
Name = a.Name,
};
Method Syntax:
var result = list.Select(r => new TemporaryHolderClass
{
Id = r.Id,
Name = r.Name
});
You can also project to the same class, provided you are not trying to project to classes generated/created for LINQ to SQL or Entity Framework.
My summary is it takes results (or a subset of results) and allows you to quickly restructure it for use in the local context.
The select clause produces the results of the query and specifies the
"shape" or type of each returned element. For example, you can specify
whether your results will consist of complete Customer objects, just
one member, a subset of members, or some completely different result
type based on a computation or new object creation.
Source: http://msdn.microsoft.com/en-us/library/bb397927.aspx
There are a lot of possible uses for this but one is taking a complex object which of many other contains a property that is a string -- say Name -- and allows you to return an enumeration with just the entries of Name. I believe you can also do the opposite -- use that property ( for example) and create / return new type of object while passing in a property or properties.
It means "mapping". Map each element of a sequence to a transformed sequence. I hadn't comprehended its meaning before I looked at the image.
Where does the meaning of the word come from?
Simply, math! https://mathworld.wolfram.com/Projection.html

unable to get multiple entries in SelectEntries of DotNetZip

I'm trying to use DotNetZipLib-DevKit-v1.9 in my MVC3 Project to extract the files to a specific folder.
What i want is -- How to add multiple entries in zip.SelectEntries method.
Here is my code in controller action:
public ActionResult ExtractZip(string fileName, HttpPostedFileBase fileData)
{
string zipToUnpack = #"C:\Users\Public\Pictures\Sample Pictures\images.zip";
string unpackDirectory = System.IO.Path.GetTempPath();
using (ZipFile zip1 = ZipFile.Read(zipToUnpack))
{
// here, we extract every entry, but we could extract conditionally
// based on entry name, size, date, checkbox status, etc.
var collections = zip1.SelectEntries("name=*.jpg;*.jpeg;*.png;*.gif;");//This shows `0` items in collections
foreach (var item in collections)
{
item.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}
}
return Json(true);
}
In this line var collections = zip1.SelectEntries("name=*.jpg;*.jpeg;*.png;*.gif;"); if i specify only single extension ,it works fine
ex:
var collections = zip1.SelectEntries("name=*.gif"); this works good
I've also seen SelectEntries method here, but it doesn't help though
How to add multiple entries ?
Finally i could answer my own question.
Inorder to select multiple entries we need to use OR and to select multiple entries use the following code:
var collections = zip1.SelectEntries("(name=*.jpg) OR (name=*.jpeg) OR (name=*.png) OR (name=*.gif)");
foreach (var item in collections)
{
item.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}

Are there simple way to receive Map instead of List when using Spring JdbcTemplate.query?

getSimpleJdbcTemplate().query(sql, getMapper()); returns List, but I need a Map where key will be store data of one of the field of object. For example, I have object named "Currency" which has fields: id, code, name, etc. Code above will return List object, but I want to get currency by id from Map. Now, I wrote the following code:
#Override
public Map<Integer, Currency> listCurrencies() {
String sql = "select cur_id, cur_code, cur_name ... from currencies";
List<Currency> currencies = getSimpleJdbcTemplate().query(sql, getMapper());
Map<Integer, Currency> map = new HashMap<Integer, Currency>(currencies.size());
for (Currency currency : currencies) {
map.put(currency.getId(), currency);
}
return map;
}
Are there any way to do same but without creating List object and looping inside it?
You have ResultSetExtractor for extracting values from the ResultSet. So in your case you can write a custom ResultSetExtractor which will return you the Map object.

How to return the result set with columns with Linq

I have a function inside a class that will run a Linq to Entities query (or any type of Linq query actually), and it's gonna return 2 columns in the resultset. I would like to return an object to whoever is calling my function that will allow Intellisense to know what I have returned.
Let me explain. If I have a function like this:
public static IQueryable GetInfo(MyEntityModel oEntityModel)
{
var query =
(from t in oEntityModel.Table1
from u in t.Table2
where t.Status == true &&
u.Status == true
select new
{
t.Column1,
u.Column2
})
return query;
}
What can (should) I put instead of IQueryable so that whoever calls my GetInfo function, will get Intellisense from the resultset, and show that it has a Column1 and Column2?
var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
if (linqresult.Column1 == 1)
{
foreach (var oItem in linqresult)
{
.. do stuff...
}
}
Tks
You cannot return an anonymous type from a function, they are strictly "inline" classes. When you return it, the foreach loop will only be able to interpret the result as an plain object. I guess you could use reflection to query the property names and values, however it seems much more straight forward to define a data transfer type to hold the results.
See this question, and this blog post.
So you could create a simple struct or class:
public class MyDataResult
{
public object Column1 { get; set; }
public object Column2 { get; set; }
}
Then modify your query in the function:
public static IQueryable<MyDataResult> GetInfo(MyEntityModel oEntityModel)
{
var query =
(from t in oEntityModel.Table1
from u in t.Table2
where t.Status == true &&
u.Status == true
select new MyDataResult
{
Column1 = t.Column1,
Column2 = u.Column2
})
return query;
}
Something like that should work. Note that I used "object" for the properties in MyDataResult. I don't know the types of the columns you are returning, you should use the actual types in order to get full intellisense.
You are returning a collection of anonymous types, they will be casted to objects, so when you try to iterate over them, altough they will be your objects (and they will contain your properties) at compile time they will be casted to objects:
foreach (var x in ClsLinqTeste.GetInfo(oEntityModel))
{
//x is an Object
}
You can read more about it here.
If you want to have intellisense, I suggest you create a custom class they will hold your properties and return not an anonymous type (using new {}) but object of your class (new MyClass(prop1, prop2)). You also need to change signature of your method, so it returns IQueryable<YourClass> and not just plain non-generic IQueryable.
As others have said, creating a new type to hold the two columns is usually the best option.
But if, for some reason, you don't want to do that and you are using .Net 4.0, you can use Tuple:
public static IQueryable<Tuple<Column1Type, Column2Type>>
GetInfo(MyEntityModel oEntityModel)
{
return from …
select Tuple.Create(t.Column1, u.Column2);
}
var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
foreach (var oItem in linqresult)
Console.WriteLIne(oItem.Item1, oItem.Item2);
When you return your resultset AsQueryable, the app is already able to give you intellisense, however in your example, you must specify either .FirstOrDefault if you know your collection will only have a single row, or iterate over your collection to get the items from it, like so:
This is what you're doing:
var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
if (linqresult.Column1 == 1)
{
..do stuff...
}
This is how you should do it:
var linqresult = ClsLinqTeste.GetInfo(oEntityModel);
foreach(var item in linqresult)
{
if (item.Column1 == 1)
{
..do stuff...
}
}
You must iterate over linqresult because when you query with link, it returns a result set, even if it just has one column. As with any collection, your data columns aren't available on the whole result set, only with individual items.
If you want to strongly typed enumerate a non-generic IEnumerable (IEnumerable.GetEnumerator() instead of IEnumerable<T>.GetEnumerator<T>()) you can use the Cast<>() extension, like so
var myquery = GetQueryable();
for (var item in myquery.Cast<MyDataType>())
{
// use item.Column1 directly and strongly typed with intellisense
}

How to access data into IQueryable?

I have IQueryable object and I need to take the data inside the IQueryable to put it into Textboxs controls. Is this possible?
I try something like:
public void setdata (IQueryable mydata)
{
textbox1.text = mydata.????
}
Update:
I'm doing this:
public IQueryable getData(String tableName, Hashtable myparams)
{
decimal id = 0;
if (myparams.ContainsKey("id") == true)
id = (decimal)myparams["id"];
Type myType= Type.GetType("ORM_Linq." + tableName + ", ORM_Linq");
return this.GetTable(tableName , "select * from Articu where id_tipo_p = '" + id + "'");
}
public IQueryable<T> GetTable<T>(System.Linq.Expressions.Expression<Func<T, bool>> predicate) where T : class
{
return _datacontext.GetTable<T>().Where(predicate);
}
This returns a {System.Data.Linq.SqlClient.SqlProvider+OneTimeEnumerable1[ORM_Linq.Articu]}`
I don't see any method like you tell me. I see Cast<>, Expression, ToString...
EDIT: Updated based on additional info from your other posts...
Your getData method is returning IQueryable instead of a strongly typed result, which is why you end up casting it. Try changing it to:
public IQueryable<ORM_Linq.Articu> getData(...)
Are you trying to query for "Articu" from different tables?
With the above change in place, your code can be rewritten as follows:
ORM_Linq.Articu result = mydata.SingleOrDefault();
if (result != null)
{
TextBoxCode.Text = result.id.ToString();
TextBoxName.Text = result.descrip;
}
If you have a single result use SingleOrDefault which will return a default value if no results are returned:
var result = mydata.SingleOrDefault();
if (result != null)
{
textbox1.text = result.ProductName; // use the column name
}
else
{
// do something
}
If you have multiple results then loop over them:
foreach (var item in mydata)
{
string name = item.ProductName;
int id = item.ProductId;
// etc..
}
First, you should be using a strongly-typed version of IQueryable. Say that your objects are of type MyObject and that MyObject has a property called Name of type string. Then, first change the parameter mydata to be of type IQueryable<MyObject>:
public void setdata (IQueryable<MyObject> mydata)
Then we can write a body like so to actually get some data out of. Let's say that we just want the first result from the query:
public void setdata (IQueryable<MyObject> mydata) {
MyObject first = mydata.FirstOrDefault();
if(first != null) {
textbox1.Text = first.Name;
}
}
Or, if you want to concatenate all the names:
public void setdata(IQueryable<MyObject> mydata) {
string text = String.Join(", ", mydata.Select(x => x.Name).ToArray());
textbo1.Text = text;
}
Well, as the name suggests, an object implementing IQueryable is... Queryable! You'll need to write a linq query to get at the internal details of your IQueryable object. In your linq query you'll be able to pull out its data and assign bits of it where ever you'd like - like your text box.
Here's a great starting place for learning Linq.
I think you find the same mental struggle when coming from FoxPro and from DataSet. Really nice, powerful string-based capabilities(sql for query, access to tables and columns name) in these worlds are not available, but replaced with a compiled, strongly-typed set of capabilities.
This is very nice if you are statically defining the UI for search and results display against a data source known at compile time. Not so nice if you are trying to build a system which attaches to existing data sources known only at runtime and defined by configuration data.
If you expect only one value just call FirstOrDefault() method.
public void setdata (IQueryable mydata)
{
textbox1.text = mydata.FirstOrDefault().PropertyName;
}

Resources