Selecting From Dynamic Attribute ASP.NET MVC3 - asp.net-mvc-3

I'm developing an ASP.NET MVC3 project which has multi-language support. I hold all the words in database and select from it according to a Session value. At present I get the value as the following:
public ActionResult Index()
{
string lang = (string)System.Web.HttpContext.Current.Session["Language"];
if (lang == "Tr" || lang == null)
{
ViewBag.Admin = db.Words.Find(10).Tr;
}
else if(lang == "En")
{
ViewBag.Admin = db.Words.Find(10).En;
}
return View();
}
The present type of Word:
public class Word
{
public int ID { get; set; }
public string Tr { get; set; }
public string En { get; set; }
}
However, the number of languages will raise, and with the present method I need to add these by hand. What I want is getting the word's "Session" language form dynamically such as (in pseudo):
ViewBag.Admin = db.Words.Find(10)."Session[Language]";
I know it should be easy but couldn't find the appropriate keywords to find this. Any idea how can I achieve this?
EDIT: I just need a way to execute an SQL String like the following:
String lang = (string)System.Web.HttpContext.Current.Session["Language"];
ViewBag.MyWord = ExecuteSQL.("SELECT " + lang + " FROM Words WHERE ID = " + 10 + " ");
EDIT 2: I tried the following lines:
ViewBag.Admin = db.Words.SqlQuery("SELECT" +
(string)System.Web.HttpContext.Current.Session["Language"] +
"FROM Words WHERE ID=10");
However, the output for this is the query itself on the screen. (SELECT Tr FROM Words WHERE ID=10)

If you are using EF as your ORM you could do something like this:
int wordId = 10;
string lang = (string)System.Web.HttpContext.Current.Session["Language"];
var query = "SELECT " + lang + " FROM Words WHERE ID = {0}";
var word = context.Database.SqlQuery<string>(query, wordId).FirstOrDefault();
See here for more info on raw sql queries:
http://msdn.microsoft.com/en-us/data/jj592907.aspx
NOTE: The above could be open to sql injection, probably best to test that it's a 2 character language code before sending the sql request to the server.

You could do it by reflection. Just get the property by the language-key.
Here is some code:
Word word = ...
string lang = (string)System.Web.HttpContext.Current.Session["Language"];
PropertyInfo pi = typeof(Word).GetProperty(lang);
return pi.GetValue(word, null);
I did not at exception handling.

You could use an expression/delegate.
Write a methode returning the expression depending on Session["Language"].
private string GetLanguageStringByKey(int key){
return GetFuncByLanguage()(db.Words.Find(key));
}
private Func<Word,string> GetFuncByLanguage(){
string lang = (string)System.Web.HttpContext.Current.Session["Language"];
Func<Word, string> func;
switch(lang){
case "En":{
func = w => w.En;
break;
}
default:{
func = w => w.Tr;
break;
}
}
return func;
}
public ActionResult Index()
{
ViewBag.Admin = GetLanguageStringByKey(10);
return View();
}

Related

Is there another way of converting a value entered by a user in an entry without using Convert?.... (Convert.ToDouble or Convert.ToInt)

I am using syncfusion numeric textbox because I want the user to enter double value into the textbox. But when i use the ConvertToDouble or ToInt if it's null then it returns a value of 0. Is there any option I can use for conversion?
//from database
public double rain1vol { get; set; }
[MaxLength(3)]
public double rain2vol { get; set; }
//user entered to database
Post post = new Post()
{
rain1vol = Convert.ToDouble(Sfrain1Entry.Value),
rain2vol = Convert.ToDouble(Sfrain2Entry.Value),
rain2vol = Sfrain2Entry.Value == null ? null : Convert.ToDouble(Sfrain2Entry.Value);
//this is the line i've tried but has error
// no implicit conversion between null and int.
// rain1vol = rain1Entry.Text,
//rain2vol = rain2Entry.Text
};
You can use method String.IsNullOrEmpty() to check the value and try- catch to achieve this .
For example, you can do like this:
var value = Sfrain1Entry.Text;
if (!String.IsNullOrWhiteSpace(value))
{
double result1;
try
{
result1 = Convert.ToDouble(value);
System.Diagnostics.Debug.WriteLine("The input is : " + result1);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Exception: " + ex.Message);
}
}
else if (value.Trim().Length == 0)
{
System.Diagnostics.Debug.WriteLine("The input is IsWhiteSpace...");
}
else {
System.Diagnostics.Debug.WriteLine("The input is invalid...");
}
Note:
You can use method String.IsNullOrWhiteSpace to filter the input data.
After that , you can use method value.Trim().Length == 0 to verify if it is whitespaces.
You can adjust the code according your requirement.

Linq to Sql Using a function to set a value

I wanted to get from a database a IEnumerable<T> and within the 'Select' method using a function to return a string value. But I always get back the
'method cannot be translated into a store expression'
error.
I already took a look all the post on Stack Overflow about the error 'LINQ to Entities does not recognize the method .... and this method cannot be translated into a store expression"
The only way that I found to get around this error is apply the function after the query has run.
void Main()
{
int eventId = 17;
IEnumerable<OccurrenceDropDownList> model = Occurrences.Select (s => new OccurrenceDropDownList
{
OccurrenceId = s.OccurrenceId,
Name = s.Name
})
.AsEnumerable()
.Select(m => new OccurrenceDropDownList
{
OccurrenceId = m.OccurrenceId,
Name = m.Name,
Selected = setSelected(m.OccurrenceId, eventId)
}).AsEnumerable();
foreach(var item in model)
{
Console.WriteLine(item.Name + " - id : " + item.OccurrenceId + " " + item.Selected);
}
}
public class OccurrenceDropDownList
{
public int OccurrenceId { get; set; }
public string Name { get; set; }
public string Selected { get; set; }
}
static string setSelected(int occurrence, int selectedid){
if(occurrence == selectedid){
return "selected";
}
return "";
}
Is there any way to apply the function as result of the first query?
It should be simplier:
int eventId = 17;
IEnumerable<OccurrenceDropDownList> model = Occurrences
.Select(s => new OccurrenceDropDownList
{
OccurrenceId = s.OccurrenceId,
Name = s.Name,
//magic ternary if
Selected = (eventId == s.OccurrenceId) ? "selected" : String.Empty
});
That's all. I used ternary if operator that should be translated to SQL.

Concatenate Datetime and string and bind result to dropdownlist using Json method

I want to concatenate DateTime field and string field in MVC application.
I want Linq to Entities query to solve this. Here is my SQL query which I want in Linq.
Select accountid,TourID, ' ('+ convert(nvarchar(20), fromdate ,105) +')' + purpose as TourDetails
from Tour
where AccountID=#AccID;
As shown in above query I want to concat fromdate and purpose. I want to pass result of this query as JSON result.
Something like this:
public class Tour
{
public int accountid { get; set; }
public int TourID { get; set; }
public DateTime date { get; set; }
public string purpose { get; set; }
}
var t = new List<Tour>
{
new Tour
{
accountid = 1,
TourID = 2,
date = DateTime.Now,
purpose = "Testing"
}
};
var output = t.Where(c => c.accountid == accId).Select(k => new
{
accountid = k.accountid,
TourID = k.TourID,
TourDetails = k.date.ToString() + k.purpose
}).ToList();
var o = JsonConvert.SerializeObject(output);
You can use something like this if you're in a MVC Controller requiring an ActionResult as output :
//here 'context' is your DbContext implementation and Tours is your DbSet.
var TourDetails= context.Tours.Where(t=>t.AccountID==_AccID)
.Select(s=>new {
AccountID = s.accountid,
TourID = s.TourID,
//s.fromdate.ToString("yyyyMMddHHmmss") use this to format your date if needed
TourDetails = s.fromdate.ToString() + s.purpose
})
.ToList();
//JsonRequestBehavior.AllowGet only if your not using POST method
return Json(TourDetails, JsonRequestBehavior.AllowGet);

LINQ sorting on sub table converted to CSV

I have an EF model (note joined partial classes togther for clarity)
public class Product
{
public System.Guid ProductID { get; set; }
public string Product{ get; set; }
public virtual ICollection<Module> Modules { get; set; }
[NotMapped]
public string ModulesCSV
{
get
{
string retList = "";
foreach (Module aModule in Modules)
{
if (retList.Length > 0)
retList += ", ";
retList += aModule.Module.Trim ();
}
return retList;
}
}
}
now I need to sort on the CSV as well as the other columns, I realise that link to sql has problems wth this. My normal sort cannot do this I was wondering if anyone knows a good way of doing it va LINQ and could please share it?
The current sort line is where 'sort' is the column name and 'sortdir' is "ASC" or "DESC" which works a treat for the other columns.
query = db.Products.AsExpandable().Where(predicate).OrderBy(sort + " " + sortdir);
Not pretty or as efficient but
if (sort != "CSV") // as non ddb column has to be sorted on list
query = db.Products.AsExpandable().Where(predicate).OrderBy(sort + " " + sortdir);
else
{
query = db.Products.AsExpandable().Where(predicate);
if (sortdir=="ASC")
{
query = db.Products.AsExpandable().Where(predicate).ToList<Product>().AsQueryable <Product> ();
query = query.OrderBy(r => r.GetType().GetProperty(sort).GetValue(r, null));
}
else
{
query = db.Products.AsExpandable().Where(predicate).ToList<Product>().AsQueryable <Product> ();
query = query.OrderByDescending(r => r.GetType().GetProperty(sort).GetValue(r, null));
}
}

Spring.Caching.AspNetCache - Condition based on ReturnValue - Condition in Spring Expression Language

I use Cache Aspect with ASP.NET Cache. I need create condition based on ReturnValue.
I simplified my problem. I use CacheResult aspect on method wich return simple POCO object.
Here is definition:
public class MyData
{
public string MyProperty { get; set; }
}
public class MyResponse
{
public int MyId { get; set; }
public MyData [] Result { get; set; }
}
I need create condition for cache - Cache result only if MyResponse.MyData.Lenght is bigger then batch limit.
[CacheResult("AspNetCache", "'MyResponse.MyId=' + #id",
Condition = "MyResponse.Result.Length > #batchLimit")]
public MyResponse GetResponse(int id, int batchLimit)
{
Thread.Sleep(5000);
return new MyResponse
{
MyId = 1,
Result =
new MyData[]
{
new MyData {MyProperty = "A"}, new MyData {MyProperty = "B"},
new MyData {MyProperty = "C"},
}
};
}
I tried this definition of condition:
Condition = "MyResponse.Result.Length > #batchLimit"
I got this error:
'MyResponse' node cannot be resolved for the specified context
[Sample.MyResponse].
So I tried second version:
Condition = "'MyResponse.Result.Length' > #batchLimit"
Finished with error:
Cannot compare instances of [System.String] and [System.Int32] because they cannot be coerced to the same type.
I google it I can use keyword ReturnValue something like this:
Condition = "#ReturnValue != null"
But I don't know how I can access to MyResponse.MyData.Length.
the context for the evaluation of the condition expression is the return value, so just do this:
Condition = "Result.Length > #batchLimit"
equivalent to
Condition = "#root.Result.Length > #batchLimit"

Resources