I use to linq to sql to fill a gridview:
var results = from r in db.MyForm1_hosps
where r.recordId == recordId
orderby r.hospId
select new { r.hospId, r.which, r.description };
if (results.Count() > 0)
{
Form_1_hosp.DataSource = results;
Form_1_hosp.DataBind();
}
later during OnRowDataBound, i call the following code to fill in the value of a radiobuttonlist
if (e.Row.RowType == DataControlRowType.DataRow)
{
RadioButtonList rbl = e.Row.FindControl("which") as RadioButtonList;
if (rbl != null)
{
DataRowView rowView = (DataRowView)(e.Row.DataItem);
LoadRadioButtonList(rowView["which"], rbl);
}
}
I get the following error:
Unable to cast object of type '<>f__AnonymousType1`3[System.Int32,System.Int16,System.String]' to type 'System.Data.DataRowView'.
I understand that an anonymous object cannot be cast to a datarowview, but what can I cast to in order to get the value of "which"
You should define a proper class to describe your data, and then you will be able to cast to this class.
// replace with proper names and types, as appropriate
class MyData
{
public int HospId { get; set; }
public string Which { get; set; }
public string Description { get; set; }
}
Update your query's select to utilize this class for the projection
select new MyData
{
HospId = r.hospId,
Which = r.which,
Description = r.description
};
And then use the type for the cast.
MyData obj = (MyData)(e.Row.DataItem);
LoadRadioButtonList(obj.Which, rbl);
There are other techniques for dealing with this, such as using dynamic and letting the runtime figure it out, or using a CastByExample<T> method (you can look it up, but I consider it faily hack-ish), but this is in my opinion the cleanest thing to do.
You could arguably also simply omit the projection and use the full object
select r;
At which point you would simply cast to the type of the elements in db.MyForm1_hosps, which is presumably MyForm1_hosp (you would have to verify). The counter against this approach would be if your UI container is auto-generating columns and this class contains more data than you wish to display, in which case, you would want to continue with the projection into a smaller construct.
Anthony's answer worked perfectly for me as well, though I'm doing things slightly differently. My goal is to display information related to tax filings and electronic funds transfers.
I'm using a RadioButtonList in an ItemTemplate. Each added item has it's own value ("Y" or "N") which corresponds to the string stored in the database.
<asp:TemplateField HeaderStyle-CssClass="TableHeader" HeaderText="Pay Estimate by EFT?" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:RadioButtonList ID="rdoPayEstbyEFT" runat="server">
<asp:ListItem Value="Y">Yes</asp:ListItem>
<asp:ListItem Value="N">No</asp:ListItem>
</asp:RadioButtonList>
</ItemTemplate>
</asp:TemplateField>
I created a class called EFT to define all the data I'm retrieving in my LINQ to SQL statement
public class EFT
{
public int JUR_ID {get; set;}
public string JUR_NAME {get; set;}
public DateTime FYE {get; set;}
public int STATE {get; set;}
public string ENT_NAME { get; set; }
public string ENT_ABBREV { get; set; }
public string TYPE_NAME { get; set; }
public int RETURN_ID { get; set; }
public string EFT_EST { get; set; }
public string EFT_EXT { get; set; }
public string EFT_RETURN { get; set; }
}
then modified the LINQ to SQL to select a new instance of that class (jurisdictions, entity, taxtypes, and returns all reference joins that are not displayed here).
select new EFT {JUR_ID = jurisdictions.ID, JUR_NAME = jurisdictions.NAME, FYE = jurisdictions.FYE.Value , STATE = jurisdictions.STATE.Value , ENT_NAME = (entity.NAME.Contains(",") ? entity.NAME.Substring(0, entity.NAME.IndexOf(",") -1).ToString() : entity.NAME ), ENT_ABBREV = entity.ABBREV, TYPE_NAME = taxtypes.TYPE, RETURN_ID = returns.RETURN_ID.Value, EFT_EST = returns.EFT_EST, EFT_EXT = returns.EFT_EXT, EFT_RETURN = returns.EFT_RETURN }
).ToList();
Then in my RowDataBound I'm extracting the "Y" or "N" value from the database and assigning that string to the selected value.
RadioButtonList rdoPayEstbyEFT = (RadioButtonList)e.Row.FindControl("rdoPayEstbyEFT");
EFT rowView = (EFT)e.Row.DataItem;
string strESTbyEFT = rowView.EFT_EST.ToString();
rdoPayEstbyEFT.SelectedValue = strESTbyEFT;
Works like a charm!
Related
I would like to fetch the column names from List. As I have a class
public class DetailView
{
public string SiteName { get; set; }
public string ItemType { get; set; }
public string AssetStorage { get; set; }
}
and in some method in controller am filling the data into Session. Now I want to get the column names for some reason. Am putting my session data into that list.
List<DetailView> objgrdDtls = new List<DetailView>();
objgrdDtls = (List<DetailView>)Session["datasetVal"];
I would like to have the Column name. Pleas note by doing the below code i got the value of that particular column name. restult1 has the column value.
var result1 = objgrdDtls.Where(p => p.SiteName.ToLower().Contains(txt1));
But all i need is Column name. So how do i get that.
stringColumnname = objgrdDtls.get(columnaname => some filter)?
Is this is the way how to get column names?
Not sure how to get the column name one by one?
Thanks.
You can use reflection to get the column name. Here is the runnable example to get the column name of DetailView.
using System;
using System.Reflection;
public class DetailView
{
public string SiteName { get; set; }
public string ItemType { get; set; }
public string AssetStorage { get; set; }
}
public class Example
{
public static void Main()
{
DetailView fieldsInst = new DetailView();
// Get the type of DetailView.
Type fieldsType = typeof(DetailView);
PropertyInfo[] props = fieldsType.GetProperties(BindingFlags.Public
| BindingFlags.Instance);
for(int i = 0; i < props.Length; i++)
{
Console.WriteLine(" {0}",
props[i].Name);
}
}
}
Var result1 will give the list of DetailView Objects which meet the condition "SiteName.ToLower().Contains(txt1)". It will not be a value. Can you please clarify what do you mean by column value. However, For selecting a particular column value, You can append ".Select(p => p.AssetStorage)".
I am doing a project and can't make a Seletect Value from a list get the right value.A list is generated from a class UserDepartment,in this class I have this basically:
public class UserDepartment
{
public long ID { get; set; }
public string Description { get; set; }
public User UserResponsible { get; set; }
}
The Problem is that I need a value from the class userResponsible,inside there is a value called EDV, I need this value but I don't know how to get.See this image below:
If I use " ListBeneficiaryArea.DataValueField = "ID"; ",I get the ID value normally,but i cant get the EDV value, I already tried "EDV","UserResponsible.EDV" and "UserResponsible"but it didn't work.
There is other way for me to get the UserResponsible.EDV in the DataValueField?
After the change in DataSource i received this error:
You can change your DataSource to the following:
ListBeneficiaryArea.DataSource = from a in lstBUAreas
select new { ID, EDV = a.UserResponsible.EDV };
Then you can do:
ListBeneficiaryArea.DataTextField = "ID";
ListBeneficiaryArea.DataValueField = "EDV";
We are returning a generic List to a GridView, which then auto generates columns to show a report:
//Generate List
List<Stock> allStock = blStock_Collection.getAll();
//export custom view for report datagrid
return (from myStock in allStock
select new
{
myStock.Category,
myStock.Description,
myLowStock.UnitPrice,
myLowStock.CurrentQuantity
});
Our client has asked that we now provide multi-lingual support on our site (English & Polish), specifically the column headers on grids. We would therefore need to get rid of the auto generate option on all our data grids, and add in the translations manually for each column.
I was wondering is there a way to do this when generating the datasource, which would save us a hell of a lot of time, e.g. changing this line:
myStock.Category,
to something like:
languagePack.Category = myStock.Category,
This is of course throwing a 'Invalid anonymous type member declarator' error. Any advice?
Maybe I misread something, but if you just want to put your language into it (LanguagePack is just a class holding your values):
class LanguagePack
{
public int Category { get; set; }
public string Description { get; set; }
public decimal UnitPrice { get; set; }
public int CurrentQuantity { get; set; }
public int LanguageName { get; set; }
}
return (from myStock in allStock
select new LanguagePack
{
Category = myStock.Category,
Description = myStock.Description,
UnitPrice = myLowStock.UnitPrice,
CurrentQuantity = myLowStock.CurrentQuantity,
LanguageName = "Polish" // or english or whatever... maybe LanguageId or something corresponding to your model
});
I have two classes - Record and RecordModified
public class Record
{
public int RecordID { get; set; }
public int FacilityID { get; set; }
public int NewAID { get; set; }
public string OldID { get; set; }
public string Data { get; set; }
public int SyncStatusID { get; set; }
public int RecordTypeID { get; set; }//RecordTypeID is integer here.
}
The second class
public class RecordModified
{
public int RecordID { get; set; }
public int FacilityID { get; set; }
public int NewAID { get; set; }
public string OldID { get; set; }
public string Data { get; set; }
public int SyncStatusID { get; set; }
public string RecordTypeText { get; set; }//RecordTypeText is string here.
}
I have a list of Record with at least 100 Record objects, now I have to convert the List<Record> into List<RecordModified>. The RecordTypeID property of the Record class has to be converted to the property RecordTypeText of RecordModified using enums which are in a different class.
Code snippet on how I'm trying to convert:
foreach(Record r in List<Record>)
{
switch(r.RecordTypeID)
{
case (int)MyEnum.One:
listofRecordModified.Add(new RecordModified{RecordTypeID=r.RecordTypeID,...,**RecordTypeText=(MyEnum.One).ToString()})** // Notice this
break;
...........//75 more cases.
}
This solution works fine, but the problem is lot of codes and I don't think its efficient. There must be some better way to do that. Please suggest.
I think you can use ConvertAll Method along with this
List<Record> t = new List<Record>();
var result = t.ConvertAll(x => new RecordModified()
{
RecordTypeText = ((MyEnum)x.RecordTypeID).ToString()
});
If your sole problem is the conversion of the index of an enum to its text, you could use GetNames and use the index of the to get the name of the enum value used.
string text = Enum.GetNames(typeof(MyEnum))[r.RecordTypeID];
This way, you don't need the switch statement, and you can revert to one line only.
You can just use the You can do using the (MyEnum)x.RecordTypeID to cast the integer value to matching enum value. and then use that .ToString() to get string value.Linq Lambda expressions as below,
var result = RecordList.Select(x=>new RecordModified{
RecordTypeID=x.RecordTypeID,
...,
RecordTypeText=((MyEnum)x.RecordTypeID).ToString()
});
You can also use the ConvertAll as,
var result = RecordList.ConvertAll(x => new RecordModified()
{
RecordTypeText = ((MyEnum)x.RecordTypeID).ToString()
});
Select is a LINQ extension method and works on all IEnumerable<> objects whereas ConvertAll is implemented only by List<>. The ConvertAll method exists since .NET 2.0 whereas LINQ was introduced with 3.5.
You should favor Select over ConvertAll as it works for any kind of list, but they do the same basically.
I believe you have each switch statement for each MyEnum value?
That is a lot of repeated code, that's true.
Why don't you just convert int to text value directly?
You can do it like this for more readability
foreach(Record r in List<Record>)
{
MyEnum myEnum = (MyEnum)r.RecordTypeID;
string stringValue = myEnum .ToString();
listofRecordModified.Add(new RecordModified{RecordTypeID=r.RecordTypeID, ...,**RecordTypeText=stringValue })** // Notice this
}
I am trying to create a binding source for a gridview that contains the datasource for a child gridview. I have attempted it in the following way:
I have 3 tables:
Patients: id(PK), fname, fname
Study: id(FK),study_id(PK),treatment_site,treatment_type,physician,dosimetrist
Study_Status:study_id(PK,FK),hasContours,hasPlan,isReady
I have the following model:
public class myPatient
{
public string fname { get; set; }
public string lname { get; set; }
public bool hascontours { get; set; }
public bool hasplan { get; set; }
public bool isready { get; set; }
public IEnumerable<editPatient> epr{ get; set; }
}
public class editPatient
{
public string fname { get; set; }
public string lname { get; set; }
public string txsite { get; set; }
public string txtype { get; set; }
public string physician { get; set; }
public string dosimetrist { get; set; }
}
public class myPatientList : List<myPatient>
{
public myPatientsList()
{
AddRange(getMyPatients().ToList());
}
public IEnumerable<myPatient> getMyPatients()
{
Connection plan_trackerEM = new Connection();
return from np in plan_trackerEM.patients
join ns in plan_trackerEM.studies on np.ID equals ns.Id
join nss in plan_trackerEM.study_status on ns.study_id equals nss.study_id
where ns.dosimetrist == App.userClass.user_id || ns.physician == App.userClass.user_id)
select new myPatient()
{
fname = np.fname,
lname = np.lname,
hascontours = nss.hasContours,
hasplan = nss.hasPlan,
isready = nss.isReady,
epr = getEditPatients(ns.study_id).ToList()
};
}
public IEnumerable<editPatient> getEditPatients(long study_id)
{
Connection plan_trackerEM = new Connection();
return from np in plan_trackerEM.patients
join ns in plan_trackerEM.studies on np.ID equals ns.Id
where ns.study_id == study_id
select new editPatient()
{
fname = np.fname,
lname = np.lname,
txsite = ns.treatment_site,
txtype = ns.treatment_type,
physician = ns.physician,
dosimetrist = ns.dosimetrist
};
}
}
Then I bind the data using XML
<local:myPatientsList x:Key="mPL"/>
<CollectionViewSource x:Key="MP" Source="{StaticResource mPL}"/>
<CollectionViewSource x:Key="EP" Source="{Binding epr, Source={StaticResource MP}}"/>
This errors out with: {"LINQ to Entities does not recognize the method 'System.Collections.Generic.List1[Plan_Tracker.editPatient] ToList[editPatient](System.Collections.Generic.IEnumerable1[Plan_Tracker.editPatient])' method, and this method cannot be translated into a store expression."}
Any pointers on how to get this to work would be greatly appreciated. The data that will be stored in the field "epr" will need to be editable by the user.
EDIT 2013-05-21
Ok, I might be getting closer with a very odd work around.
I removed
epr = getEditPatients(ns.study_id).ToList()
from the query results and then added after the query results:
List<mypatientResults> new_tmp_mp = new List<mypatientResults>();
foreach (mypatientResults tmp_mp in _mp)
{
tmp_mp.epr = getEditPatients(tmp_mp.sid).ToList();
new_tmp_mp.Add(tmp_mp);
}
return new_tmp_mp;
This is now runnign without error, but I have not been successful (YET) in using epr as a datasource. I have added it as a column to a datagrid for debugging and it does report it as a System.Collections.Generic.List`1[Plan_Tracker.editpatientResults], but that could be from declaring the variable and not because of the data.
I am still overmy head here and could use help figuring this out.
I am unsure the reasoning, possible that Linq does not like the tree-like structure?!? regardless the edited text above was the solution. I was able to successfully create custom hierarchy and show it in a parent/child gridview.