Binding to inherited linq types in asp.net
I have a Linq-to-SQL data model that includes a type Party
that is subclassed twice for Company
and Individual
. I am trying to link two repeaters with Linq-to-SQL queries as follows
Dim oComp As IEnumerable(Of Company)
Dim oInd As IEnumerable(Of Individual)
oComp = From oP As Company In ERM.Parties _
Where TypeOf (oP) Is Company And _
oP.Name.StartsWith(sSearchString)
oInd = From oP As Individual In ERM.Parties _
Where TypeOf (oP) Is Individual And _
(oP.FirstName.StartsWith(sSearchString) Or _
oP.LastName.StartsWith(sSearchString))
rptIndividuals.DataSource = oInd
rptCompanies.DataSource = oComp
rptCompanies.DataBind()
rptIndividuals.DataBind()
when i execute the code oComp
and oInd
as expected IEnumerable<Company>
and IEnumerable<Individual>
but i get the following exception when the first call is reachedDataBind
Fixing System.MissingMethodException was not handled by user code Message = "Constructor by type" System.Data.Linq.Provider.DataBindingList
1[[DataModel.Party, DataModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' not found." Source="mscorlib" StackTrace: at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) at System.Data.Linq.Provider.BindingList.Create[T](DataContext context, IEnumerable
1 sequence) in System.Data.Linq.DataQuery1.GetNewBindingList() at System.Data.Linq.DataQuery
1.System.ComponentModel.IListSource.GetList () at System.Web.UI.DataSourceHelper.GetResolvedDataSource (Object dataSource, String dataMember) at System.Web.UI.WebControls.ReadOnlyDataSource.System.Web.UI.IDataSource.GetView viewName) to System.Web.UI.WebControls.Repeater.ConnectToDataSourceView () to System.Web.UI.WebControls.Repeater.GetData () to System.Web.UI.WebControls.Repeater.CreateControlHierarchy (Boolean useDataSource) to System.Web.UI.WebControls.Repeater.CreateControlHierarchy (Boolean useDataSource) .UI.WebControls.Repeater.OnDataBinding (EventArgs e) at System.Web.UI.WebControls.Repeater.DataBind () at parties.lbHiddenPostback_Click (object sender, EventArgs e) at \ parties.aspx.vb: line 491 at System. Web.UI.WebControls.LinkButton.OnClick (EventArgs e) in System.Web.UI.WebControls.LinkButton.RaisePostBackEvent (String eventArgument) at System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent (String eventArgument) at System.Web.UI.Page.RaisePostBackment (System.Web.UI.Page.RaisePostBackEvent (System IPostBackEvent) .UI.Page.RaisePostBackEvent (NameValueCollection postData) at System.Web.UI.Page.ProcessRequestMain (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) InnerException:ProcessRequestMain (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) InnerException:ProcessRequestMain (Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) InnerException:
if i then select everything as sides, but like this: everything works fine
Dim oComp As IEnumerable(Of Party)
Dim oInd As IEnumerable(Of Party)
oComp = From oP In ERM.Parties _
Where TypeOf (oP) Is Company And _
CType(oP, Company).Name.StartsWith(sSearchString)
oInd = From oP In ERM.Parties _
Where TypeOf (oP) Is Individual And _
(CType(oP, Individual).FirstName.StartsWith(sSearchString) Or _
CType(oP, Individual).LastName.StartsWith(sSearchString))
rptIndividuals.DataSource = oInd
rptCompanies.DataSource = oComp
rptCompanies.DataBind()
rptIndividuals.DataBind()
There is nothing in the repeater to do with the returned data, just a label in the item template to show me how many records are being returned for each request.
It doesn't make sense to me that I need to bind to the parent type, I won't be able to access the Individual and Company related attributes without first clicking on that type!
You can fix this by using .ToArray ()
when you set the DataSource
repeater property ...
rptCompanies.DataSource = oComp.ToArray ()
I'm not sure if I know why this works, but I tried it and it seems to have solved the problem!