Entity Framework and MySql Stored Procedures - c#

I am working with Entity Framework 4.0, VS 2010, MySql server database, and mysql-connector-net-6.4.4 for connection purpose. It works fine, that said, it can generate Model classes, csdl, ssdl etc files well. But, for stored procedures it doesn't work.
Here is what happens..
Right clicked on an SP from Model Browser, select [Add Function Import]. This opened a dialog box
Filled appropriate values like, Function Import Name, Stored Procedure Name
Click on [Get Column Information]. This results into some Grid filled up at the bottom of this button. In the grid, there is a column named [EDM Type]. This column shows [Not supported] due to some unknown reason :(
Now, clicked on [Create New Complex Type]. This goes OK, without Error
Now, clicked on OK button
After doing all above steps, there is no Complex Type created in the code however, which is the problem.
Can anyone please help?

The generated Complex Type is in the Complex Types folder in the Model part of the Model Browser.
To access ti in code, use it as any other Entity
MyComplexType ct = new MyComplexType();
And you can use it as a result type for your stored procedure:
List<MyComplexType> info = ctx.GetAllEmployees().ToList<MyComplexType>();
You must ensure that the GridView's columns mappings match the Complex Type's properties, or that the GridView's property AutoGenerateColumns is set to true.

Related

Effective way of displaying results of stored procedure with interactive button columns

Apologies if the title is vague - I will explain in as much detail as possible the problem.
I have an ASP.NET webpage which queries a TSQL database using a stored procedure, the query is run on Page_Load. The procedure returns a dataset (with ID column, RequestID). The contents are essentially a list of data-specific requests that need to be approved or rejected as exceptions to another workflow (not entirely relevant but may help explain my approach)
I'd like to display the results of this procedure in a grid (currently this is easy enough) however I'm running into problems when trying to add buttons that allow the user to interact with the data, e.g. I'd like 'Reject/Approve' buttons.
When one of these buttons is pressed the relevant stored procedure would be run, with the RequestID of the row pressed passed as a parameter. The idea is to have the stored procedure update an audit log and update the relevant tables accordingly (each request represent a complex data object spanning multiple tables) - for this reason the default controls aren't sufficient for select/edit/delete.
I feel like I'm doing this entirely wrong from the basic approach, which is using a gridview and trying to add custom SelectMethod/DeleteMethod's. What would be a best practice approach for doing this?
EDIT*
Here is the data table and how i'm populating it:
DataTable Requests = new DataTable();
Requests = GetRequests(connString); //Method that returns a datatable from a stored procedure
Displaying the data in a gridview as follows:
gridView.DataSource = Requests;
gridView.DataBind();
However when i add the following code, which is me trying to fire a custom method when using the default select/delete controls in a gridview i get an exception:
gridView.AutoGenerateDeleteButton = true;
gridView.AutoGenerateSelectButton = true;
gridView.SelectMethod = "ApproveRequest";
gridView.DeleteMethod = "RejectRequest";
Here is the exceptiopn (which make sense, but makes me think i'm going about this the wrong way).
Message=DataSource or DataSourceID cannot be defined on 'gridView' when it uses model binding.

DevExpress report Main and Detail reports stored procedures

I have to create an XtraReport with two sections; master and detail. For example, categories - is master and their products is detail:
Category1
Prod1
Prod2
Prod3
Category2
Prod4
Prod5
Prod6
The problem is that both categories and relevant products come from Stored Procedures. So I have 2 stored procedures, the first master stored procedure is without parameters, the second detail store procedure has the parameter of CategoryId (that comes from first Stored Procedure).
I can't find a way to set the CategoryId parameter value of the second stored procedure from the first stored procedure.
In the stored procedure designer I can see this, but I can't set the parameter value to first store procedure ID.
The solution is using xsSubreport component, create separate sub-report and attach to it.
You can pass parameters to it from outer(main) report, and it will fetch data in it based on outer parameters
https://www.youtube.com/watch?v=ZKRsXxjr_EI
I know I'm being a little late on this, but I'm sure that the DevExpress built-in data access solution (the EFDataSource component) does not support this kind of integration as the entire source is filled at once. As I understand, you need to create a Master-Detail Report. In this case, the best option here will be to define control bindings in Object Binding mode, and then, at runtime, execute both stored procedures manually using your DBContext class. Assign the first result set directly to XtraReport.DataSource. The second stored procedure should be executed at runtime several times in the DetailReportBand.BeforePrint event handler. You can get the master row's CategoryId as rootReport.GetCurrentColumnValue("CategoryID")
I hope this helps. If my explanation is not clear, I'm sure the DevExpress support team will be happy to explain more and provide you with an example (not sure why you've not done that in the first place though — StackOverflow is not meant for discussing vendor-specific products)

The data reader is incompatible with the specified class

so there are a few other similar type posts about, but none matching the simple task I am attempting.
just running a stored proc through EF6 code first in the following manner
var results = context.DataBase.SqlQuery<MyClass>("exec spGetStuff #param1, #param2", new SqlParameter[] {new SqlParameter("param1",value), new SqlParameter("param2", value2)});
I have used this method on many occasions with no issue.
the class I am mapping the results to is pretty nasty with many properties, but all that need it are marked with the [Column("dbfieldname")] attribute.
all the stored proc is doing is returning some results by using a
SELECT * FROM(
SELECT
ROW_NUMBER() OVER ( PARTITION BY X,Y,Z ORDER BY A) [RowNumber]
,*
FROM
MyTableNAme
WHERE
...) S
WHERE s.RowNumber = 1
not inserting, updating or anything fantastical like that.
The data reader is incompatible with the specified 'MyClass'. A member of the type, 'PropertyNameName', does not have a corresponding column in the data reader with the same name.
if I do change the class properties to the db column names it seems to work fine:I can change the first few properties and it will then fail on other ones in the class... however I do not really want to do that if I can possibly avoid it as most of the columns in the DB are named very badly indeed, so I guess my question is why is it ignoring the [Column()] attributes that have never failed me before.
or is the issue the row_number, which I have tried adding to the class an/or removing from the query resultsset.
We're seeing this issue too since upgrading and refactoring for EF6 from 5. Stored procedure returns and we have a Complex Type defined in our edmx. It seems that everything matches up but we get the same type of error when calling like this
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<GetColumnValueSet_Result>("GetColumnValueSet", param1, param2, param3);
So after trying a few things this is what I found. I opened my edmx and went to the Model Browser within Visual Studio. Under Function Imports I found my sproc. Right clicked and chose Function Import Mapping. It turned out that even though the complex type was correct and it appeared everything should have matched up the Function Import Mapping was thinking the sproc was returning a column called CodeValue instead of Value (which is what it was actually importing).
So for some reason when the sproc columns were gotten it go a wrong name for the mapping.

Add Geography.Lat/Long to View with the designer

I am currently working with some GIS data and using the Geography data type in MS SQL Server 2012. I am having some difficulty when trying to display the Latitude and Longitude of the Geography type using the View designer, specifically if I have a join with another table.
For example the below works fine in the view designer:
SELECT dbo.table1.ID, dbo.table1.LocationTypeID, dbo.table1.Location, dbo.table1.Location.Lat as LocLatitude, dbo.table1.Location.Long as LocLongitude
FROM dbo.table1
However, this does not:
SELECT dbo.table1.ID, dbo.table1.LocationTypeID, dbo.table2.LocationTypeName, dbo.table1.Location, dbo.table1.Location.Lat as LocLatitude, dbo.table1.Location.Long as LocLongitude
FROM dbo.table1 INNER JOIN
dbo.table2 ON dbo.table1.LocationTypeID = dbo.table2.ID
I found that if I remove the schema (dbo) and manually create the view via an SQL command it will create the View and run correctly, however, attempting to edit it later via the designer will display errors.
For reference the error the designer throws out is the "multi-part identifier could not be bound".
Whilst the manual creation of View can resolve the issue I would really like to find a way to solve this as it is bugging me but also causes issues for other people working on the project not knowing that now the only way to edit the View in future is to create an "Alter View" SQL command.
I have tried searching for an answer to this but have yet to find anything, normally this would not be an issue as I would just grab the Geography type object from the code and get the Lat/Lon there to be displayed but I need to create an export/View for a 3rd party.
Need to reference tables by aliases instead of directly. Answer provided by #MartinSmith

How to set a property value to auto increment in visual studio lightswitch 2012

i want to set a property value in a table to default auto increment,but their are no options to do so in lightswitch2012 to my knowledge which is given that i recently started learning lightswitch,very light.
ok heres the real problem,this is the table
[customer][id,customer_id,name]
i want to set customer_id by default to id unless it is manually changed to different value.
how to acheive this?
In the Entity designer make your Customer_ID not required.
Write Code for Customers_Inserted.
Then, check to see if the Customer_ID is null. If it is, copy the ID field to it.
private void Customers_Inserted(Customer entity)
{
if (entity.Customer_ID == null) {
entity.Customer_ID = entity.ID;
}
}
You're right, there is no "auto-increment" data type available in LightSwitch. The ID property auto-increments, but that's a special case, handled by LightSwitch.
If you were attaching to an external SQL database, if you added a column that was an Integer Identity column, although it'll just appear as an Integer property in LightSwitch, it would still auto-increment because that's actually done in the SQL database itself.
The problem with all auto-increment properties is that you won't get the actual value until the record is saved.
Can I ask why you need an auto-increment property?
I may be misunderstanding what you are trying to achieve, but if you are using either a table or a grid, and you want to set the values for various entities for each new row your user adds (like customer_id = id, etc.), you can use the _Changed method and Add event to programmatically set any of the new row entities.
If this is along the lines of what you're looking for, watch Beth Massi's video How Do I: Copy Data from One Row into a New Row? You should be able to adapt her code to accomplish what you have in mind I think.

Categories