Store Procedures with Dapper.Contrib - dapper

I am newbie to Dapper and I Want to use Dapper.Contrib. Is there any method we can use store procedure with Dapper.Contrib methods.
e.g The method of Dapper.Contrib is connection.GetAll<Invoice>().ToList();. I want to call store procedure in this extension methods.

For stored procedures, use .Query<T> extension.
var result = cnn.Query<Data>("spGetData", new {Id = 1},
commandType: CommandType.StoredProcedure);
Here is a Link to sql mapper extensions source code.

Related

Modify and delete document in Cloudant IBM Database

Is it possible to modify document or delete in Cloudant Database by query?
I assume the questioner is looking for equivalent functionality to SQL's:
UPDATE db SET x = 10 WHERE y > 100;
If that is the question then the answer is that Cloudant does not have such functionality, only an atomic update operation.
The equivalent of the UPDATE statement could be achieved by combining a call to the Cloudant Query API and making updates using the bulk API.
Another option is to use the couchtato iterator tool which allows bulk changes to be made to Cloudant databases.
To delete a document you have to know the document _id, if you do not know the _id then you have to look for the document in your db, retrieve it and then get the _id.
To retrieve a document you can use a selector. For example, let's say that you have a document that contains a "name" field, your selector would be something like
selector = {"name": {"$eq": "name that you want"}}
So for python code you would have something like
def retrieve_db_data(db_name, selector):
client = connect_to_db()
db = client[db_name]
results = db.get_query_result(selector)
data = results.all()
return data
In "data" you will have the _id
then you can use something like this to delete the data
def delete_document(db_name, doc_id):
client = connect_to_db()
client.connect()
db = client[db_name]
document = db[doc_id]
document.delete()

SQLALchemy - cannot reflect a SQL Server DB running on Amazon RDS

My code is simple:
app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)
db.metadata.reflect()
And it throws no errors. However, when I inspect the metadata after this reflection, it returns an empty immutabledict object.
The parameters in my connection string is 100% correct and the code works with non-RDS databases.
It seems to happen to others as well but I can't find a solution.
Also, I have tried to limit the reflection to specific tables using the "only" parameter in the metadata.reflect function, and this is the error I get:
sqlalchemy.exc.InvalidRequestError: Could not reflect: requested table(s) not available in mssql+pyodbc://{connection_string}: (users)
I've fixed it. The reflect() method of the SQLAlchemy class has a parameter named 'schema'. Setting this parameter, to "dbo" in my case, solved it.
I am using Flask-SQLAlchemy, which does not have the said parameter in its reflect() method. You can follow this post to gain access to that parameter and others, such as 'only'.
This error occurs when reflect is called without the schema name provided. For example, this will cause the error to happen:
metadata.reflect(only = [tableName])
It needs to be updated to use the schema of the table you are trying to reflect over like this:
metadata.reflect(schema=schemaName, only = [tableName])
You have to set schema='dbo' in parameter for reflect.
db.Model.metadata.reflect(bind=engine, schema='dbo', only=['User'])
and then create model of your table:
class User(db.Model):
__table__ = Base.metadata.tables['dbo.User']
and to access data from that table:

EF 6 - Stored Procedure Duplicate Result Column

I'm in the process of migrating from a legacy system. The database cannot be modified - including adding/modifying stored procedures.
I've added a stored procedure to an EDMX model successfully, it generated the following code:
public virtual ObjectResult<sp_GetUserInfoByUID_Result> sp_GetUserInfoByUID(Nullable<System.Guid> sessionID, Nullable<System.Guid> userUID)
{
var sessionIDParameter = sessionID.HasValue ?
new ObjectParameter("SessionID", sessionID) :
new ObjectParameter("SessionID", typeof(System.Guid));
var userUIDParameter = userUID.HasValue ?
new ObjectParameter("userUID", userUID) :
new ObjectParameter("userUID", typeof(System.Guid));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<sp_GetUserInfoByUID_Result>("sp_GetUserInfoByUID", sessionIDParameter, userUIDParameter);
}
However, I get the following runtime error:
The data reader is incompatible with the specified 'MyApp.Repository.sp_GetUserInfoByUID_Result'. A member of the type, 'useraccount_uid1', does not have a corresponding column in the data reader with the same name.
So it looks like EF generated two mappings: useraccount_uid and useraccount_uid1. This is because the stored procedure returns a table with two columns named useraccount_uid.
Is there a way to get round this in the EF model?
Turns out the solution was really simple, I'd just overlooked how EF modeled stored procedures. When you add a stored procedure to the Model, by default it actually adds a couple of references.
A mapping from the model to the basic function in the DB - you cannot edit these mappings.
A "Function Import" - this is the part which maps result sets to code models.
So all I had to was look for the Function Imports folder in the EDMX Model Browser. In here the stored procedure was listed. If you right-click on the function you'll see the "Function Import Mapping" option. This will open the Mappings Detail window. Here I could simply correct the column naming.

What is a dynamic apex in salesforce?

I am in the learning stages of Salesforce Apex. I have read the topic of Dynamic Apex and was not able to understand the concept. Can someone explain it how to deal with it and in which scenarios it is best to use?
Thanks in advance.
Use case 1:
You are developing a page that reads the salesforce object meta data to display the object records to the user. You want to use the describe global methods but you dont know how to combine standard SOQL with the generic SObject type.
Standard SOQL eg
Person__c [] persons = [SELECT Id, Name, Age__c, Height__c FROM Person__c];
But the describe global metadata methods returns a SObject types.
Solution:
Use the describe global methods to get a list of objects, then further get all the fields on that object. Build a SELECT statement in a local string variable with all the fields then execute the query with Database.query().
string objectfullname = 'scenario__c';
Schema.SObjectType targetType = Schema.getGlobalDescribe().get('scenario__c');
if (targetType == null) {
system.debug('Type not found: '+objectFullname);
throw new TypeNotFoundException(objectFullName);
}
Schema.DescribeSObjectResult typedescription = targetType.getDescribe();
Map<String, schema.Sobjectfield> resultMap = typedescription.Fields.getMap();
string query = 'SELECT ' + string.join(new List<string>(resultMap.keySet()), ',') + ' FROM '+ objectfullname + ' LIMIT 100';
sobject [] records = Database.query(query);
Use Case 2
You want to loosely couple your code with custom objects in a beta managed packaged so that the managed packaged can be uninstalled and upgraded.
Solution
When you use the Database.query() method, your code is not compiled against the custom object so it can be re-installed without any need for commenting out code to remove the dependency.
Use Case 3
You have a trigger that copies records to another custom object after insert according to an dynamic field mapping schema. You can't code it in the standard way [SELECT ...] because you only know what object you are inserting to at run time.
Solution
Again, use describe global methods & Database.query to get the records and type information then you can insert into the target object like normal DML.
sobject newRecord = ...
for (integer i = 0; i < fieldCount; i++) {
newRecord.put(fields[i],values[i]);
}
insert newRecord;
If you are doing bulk inserts, like always, make sure that you dont put DML (insert, update) statements in a loop.

Entity Framework CTP5 - How to Call Stored Procedure?

This may be a simple answer, but i can't see how to execute a stored procedure with EF CTP5.
In Entity Framework 4.0, we did this:
ExecuteFunction("ContainerName.StoredProcName", new ObjectParameter("Id", id)).
Which is a method on the ObjectContext.
But DbContext has no such method.
How do we call a stored proc? Is it not supported in EF CTP5?
EDIT:
I found this thread, which states you need to do this:
var people = context.People.SqlQuery("EXECUTE [dbo].[GetAllPeople]");
This raises some concerns:
1) You are now calling a stored prodedure on the set, not the context. Stored procedures should be available context-wide, not tied to a particular entity set. Just like how they are under the "Database" in SQL Server, and not under the "Table".
2) What about complex types? I previously had a complex type being returned from a stored procedure. But now, it looks as though you have to map directly to an entity? That doesn't make any sense. I have many stored procs that return a type not directly represented by an ObjectSet/DBSet, which i can't see how i can pull over.
Hope someone can clear this up for me, because from what i understand so far, i won't be able to upgrade to CTP5.
You can execute database-wide sql statements like this
using(var context = new MyContext())
{
// custum sql statement
var c = context.Database.SqlQuery<int>("SELECT COUNT(*) FROM Employees");
// returned entity type doesn't have to be represented by ObjectSet/DBSet
var e = context.Database.SqlQuery<Employee>("SELECT * FROM Employees");
// stored procedure
var q = context.Database.SqlQuery<Employee>("GetEmployees");
}

Resources