Could not determine metatable error binding list to asp.net datagridview - asp.net

I am working with the following block of code ...
List<ThemeObject> themeList = (from theme in database.Themes
join image in database.DBImages on theme.imageID equals image.imageID
into resultSet
from item in resultSet
select new ThemeObject { Name = theme.Name, ImageID = item.imageID}).ToList();
dgvGridView.DataSource = themeList;
dgvGridView.DataBind();
The list object populates fine. The datagrid is setup with 2 columns.
A textbox column for the "Name" which is bound to "Name"
An image column which is bound to the "ImageID" field
When I execute the code I receive the following error on the DataBind()
Could not determine a MetaTable. A
MetaTable could not be determined for
the data source '' and one could not
be inferred from the request URL. Make
sure that the table is mapped to the
dats source, or that the data source
is configured with a valid context
type and table name, or that the
request is part of a registered
DynamicDataRoute.
I'm not using any dynamicdataroutes as far as I can tell. Has anyone experienced this error before?

Assuming you are developing a Dynamic Data Entities web application (that's what the error you provided hints about), try this in your Page_Init:
dgvGridView.EnableDynamicData(typeof(ThemeObject));

Related

DevExpress XtraReports binding subreport datasource to report's datasource of collection

I'm having some trouble with binding a DevExpress XtraReport subreport's datasource to it's containing report's datasource. The datasource is an object collection.
If I create a basic reports with sub detail sections all is well.
For example, the object collection is a list of companies. Each company has a list of addresses and a list of contacts. What I am attempting is to create a report with two subreports side-by-side for each (detail) company.
From several web articles, I thought this approach seemed like it would work:
report.ContactSubreport.ReportSource.DataSource = report.Datasource
which I call from a script using the subreport's BeforePrint event.
I also tried setting the datamember to the name of the sub collection:
report.ContactSubreport.ReportSource.DataMember = "Contacts"
Any help or suggestions would be greatly appreciated. Thanks!
From what I gather, you need to display only child collections' records that belong to the current master record.
In this case, it's better to handle the BeforePrint event of those XRSubreports and call there the XtraReport.GetCurrentRow method for a master report. This method call will return a master record (i.e., an instance of the "Company" object). This will allow you to pass the "Company.Addresses" list to the first subreport and the "Company.Contacts" list to the second one. Thus, the details that only correspond to each "Company" will be printed in both subreports.
I accomplish XtraSubReport dynamic or runtime data binding by doing Something like this and it WORKS perfectly
(VB.NET but can easily be implemented in C#)
NOTE:
The BandKind.Detail parameter below means the subreport was placed in the Detail Band. If not then specify the band of the main report where you placed the subreport in (eg. PageHeader, ReportHeader, PageFooter, etc)
The "XrSubreportInvoiceBank" is the name of the subReport that you created in the main report. You will need to change it to the name of the subreport in your main report
Dim MyDocument As New XtraReportInvoiceHardcopy
Dim BankSubreport As XRSubreport = CType(MyDocument.Bands(BandKind.Detail).FindControl("XrSubreportInvoiceBank", True), XRSubreport)
Dim BankAccount As DataTable = New DataTable 'You can put your Data in here
BankSubreport.ReportSource.DataSource = BankAccount
BankSubreport.Visible = True

Dynamics AX 2012 - Grid Control linkPhysicalTableInstance to TempTable, first record inserted doesn't appear in Grid, fine afterwards

The problem related to using table buffers in AX 2012 with Grid Controls, where first time additions to the form's tempDB were not displayed in real time (but were persistent and subsequent additions worked fine thereafter).
I resolved the problem with help from DAX legend Martin Dráb and Brandon Weise on the Dynamics Community MSDN but I'm posting on SO in case it helps others (as I couldn't find anything close), and I don’t think it hurts the community to add more Dynamics AX content on SO. There are also some learnings to be had about how physical tables link to tempDBs and their relationship to the form's datasource.
Original thread: https://community.dynamics.com/ax/f/33/t/225120
Problem:
I have a Wizard that generates a new form at runtime, containing a Grid Control.
The Wizard passes a reference to one of its temp Tables to the form, in which I use linkPhysicalTableInstance in the runtime form's datasource init() method.
The GridControl has an add new record button, which inserts records in to the tmp table reference.
The new record is saved to the reference temp table correctly, and displays in the grid when the runtime form is closed and reopened but does not display in the grid immediately after the insert.
To add to the weirdness, after a runtime form has been created, a record inserted and then closed, subsequent run time forms do display new record insertions immediately, without needing to be re-opened. Some code snippets below.
Why does this behavior only happen for the first time that data is inserted in to the temp table, but displays fine for subsequent runs of the runtime form?
Creating the runtime form:
args = new Args(formstr(RunTimeFormName));
formRun = classFactory.formRunClass(args);
formRun .parmRuntimeFormsGridTmpDS(sysWizard.ReferenceToWizardsTableTmp()); // Passing a reference for Wizards tmpTable to form
formRun .init();
formRun .run();
formRun .wait();
formRun .detach();
RunTime Form's parmDataSourceMethod:
public void parmRuntimeFormsGridTmpDS(CommentsGridTmp _ReferenceToWizardsTableTmp)
{
ReferenceToWizardsTableTmp = _ReferenceToWizardsTableTmp;
}
DataSource init() method:
public void init()
{
super();
RuntimeFormsGridTmpDS.linkPhysicalTableInstance(ReferenceToWizardsTableTmp);
}
RunTime Form's New button clicked method:
void clicked()
{
int64 numRows;
;
// Refresh records loaded in grid DS to ensure correct number of records for setting initial index number
// Note: SomeId is passed in Args() record, its passing fine as is the number of rows count - and replacing with a static value has no effect.
select count(RecId) from ReferenceToWizardsTableTmp
where ReferenceToWizardsTableTmp.SomeId == someId;
numRows = ReferenceToWizardsTableTmp.RecId;
ReferenceToWizardsTableTmp.Comment = "Comment " + int642str(numRows + 1);
ReferenceToWizardsTableTmp.Filename = "";
ReferenceToWizardsTableTmp.someId = someId;
ReferenceToWizardsTableTmp.insert();
element .Task(#TaskF5);
// super();
}
So as described above, the first time that the runtime form is created and a record is inserted, it doesn't display. Reopening the form will display the inserted data fine. Also, after reopening the form any new records inserted appear in the grid in real time.
I originally supposed it had to be something to do with the linkToPhysicalTable and where the grid fields look for records to display…
By the way, if you have a better answer or explanation then please feel free to contribute.
Solution
I have a working solution whereby I run a select statement on the buffer reference prior to the linkPhysicalTableInstance operation (a delete_from tmptable statement has the same effect and is cheaper), which acts to initialize the buffer reference despite it being empty.
The linkPhysicalTableInstance operation then succeeds at the first run because the buffer properly exists - and changes written to the form DS are now persistent and reflected in the calling Wizard's buffer reference.
In Addition (from Brandon Weise):
In case you happen to be jumping tiers in your code, here's a small gotcha to watch out for.
https://community.dynamics.com/ax/b/dynamicsaxexperience/archive/2016/01/24/2012-unexpected-degeneration-of-insert-recordset-into-tempdb-buffer
Techniques That I Found Useful for Investigation
(Credit to Brandon Weise and Martin Dráb for these)
It does seem that using .linkPhysicalTableInstance(..) to change the underlying temp table associated with a form datasource after it
has already initialized produces some weird behavior. This seems to
be true even when you can demonstrate with .getPhysicalTableName()
that they are linked properly.
One technique to help is to create your form, and
call .init(), but not yet .run(). Then use
.linkPhysicalTableInstance() to link the freshly created temp table
underlying the data source to your external temp table buffer. In
other words, instead of trying to transplant your already created
temp table into the form's data source, let the form create the temp
table, then let the caller transplant that temp table into its own
buffer using .linkPhysicalTableInstance(). Then insert records,
then call .run(). If necessary, call .executeQuery() on the form
data source after .run().
I took a scattergun approach to printing
the table names throughout initialization and operation, and while
the two tables do eventually link correctly with the same table
name, they take a roundabout way of getting there.
Inspect the contents of a temp table while debugging, from SQL Server Management Studio using:
set transaction isolation level read uncommitted;
select * from tempdb..t107946_BE044A13A9C24283897CA1B59607CBD2;
Which is easy if you have the table name from
.getPhysicalTableName(), but even if you don't know it precisely,
it's often easy to locate with a little trial and error. select *
from tempdb.sys.tables; The table will of course start with "t" and
the table number. Often it's the most recently created one, so
sorting by create_date desc floats it to the top, but of course
there can be a pool of them.
Review Methods on a Form Data Source which methods you can use when working with records through a datasource.

Create a control based on value in a DB

I need to create a dynamically built page in my ASP.NET app (using VB). The page collects parameter information for a report.
The report information such as the name, stored procedure and the required parameters are in a DB table.
In the table I have a field 'control_type' which I am hoping I can use to be the type of control I need to create to collect the relevant parameter value for the selected report.
So, if I select Report01, I get the row form the DB for Report01 and the parameter data for that reports row tells me I need to collect an integer value into a parameter called i_company_id and the control to create to select this value form (on my dynamically created parameters page) says 'DropDownList'.
If I get the row from the DB and place that filed value into a variable, can I then do something like
dim ddl as New VaraibleName
and then I can populate the list as normal and then
panel.controls.add(ddl)
The key bit is being able to create a control where the type of control to create is in a variable or some other dynamically defined way.
I understand that the following solution delivers what you want:
Private Function createVariable(inputName As String) As Object
Dim outVariable As Object = New Object
If (inputName = "DropDownList") Then
Dim targetVariable As DropDownList = New DropDownList()
With targetVariable
'You might change here its properties (passed via Object array for example)
End With
outVariable = targetVariable
End If
'Add as many conditions as variables you are expecting
Return outVariable
End Function
Call it by doing:
Dim ddl As Object = createVariable("VariableName")
panel.Controls.Add(ddl)
If you are planning to use this code just with Controls, you can replace Object with Control (will work either way).

about Dev express Grid view runtime error

Microsoft JScript runtime error: Sys.WebForms.PageRequestManagerServerErrorException: A field or property with name 'Year' was not found in the selected data source. Possible causes of this error may be the following: an incorrect or case-insensitive spelling of the grid column name; assigning a wrong or not properly initialized data source to the grid.
i want to bind one datasource to gridview in devexpress it is loaded for first time after that i am applying some more filters with year,month and client then i will get this error what is the problem the table is showing the data but it is not bind to the Grid please tell me
Edit
ASPxGridVendor.DataSource = Nothing
ASPxGridVendor.DataBind()
ASPxGridVendor.DataSource = Session("DSGrid")
ASPxGridVendor.DataBind()
It sounds like the answer is in the exception message. The column "Year" doesn't exist in the datasource...
If you are applying your filters by posting back, you need to rebind the gridview again with your datasource

Paging on Gridview control VS-2008

If you followed my previous post
var filteredUser = from U in collection
select new {U.fname,U.lname};
gridView.DataSource = filteredUser;
gridView.DataBind();
Now I am trying to do this:
Format the column names based on properties of U. So for example if U.fname chancges to U.FirstName then I want my gridview column name to reflect the same
If I enable paging through the design view, code compiles but when I launch the web app, it fails stating 'The data source does not support server-side data paging'
Edit::Found this for item # 2
link text
1) Are you using AutoGenerateColumns="True" on your GridView or binding them yourself? I would think that (1) would work if AutoGenerateColumns is true. You lose a lot of control over how the columns are displayed, but it ought to work. If you are binding them yourself, I think you will just need to update the bound column names whenever the name of the data field changes or alias the name in the select clause so that it remains the same.
var filteredUser = from U in collection
select new {FirstName = U.fname, LastName = U.lname};
2) Does your collection support IEnumerable<U> or just IEnumerable? I believe that LINQ uses Skip() and Take() to support paging so it would need to support the generic enumerable interface.

Resources