When using SubSonic 3.0.0.3 and the StoredProcedures.tt template, the generated code won't compile and throws an error:
... 'DB' does not contain a definition for 'Provider' ...
This is in the calling method for the sproc.
StoredProcedure sp = new StoredProcedure("Company_Get", this.Provider);
Am I missing something or is there a bug in the 3.0 templates for generating wrappers around stored procedures?
I guess those of us wanting to use v3 of SubSonic are on the bleeding edge. I needed to generate the code with the context.tt as well. This corrected my problem. This is really cool stuff, but the screen casts and the docs are not keeping up with how quickly the product is evolving.
public ProcedureParameters Parameters
{
get
{
return sp;
}
set
{
sp = value;
}
}
# region "Constructors"
public ExecuteProcedures(int ParameterLength, string ConnectionString):base(true,ConnectionString)
{
sp = new ProcedureParameters(ParameterLength);
strConnection = ConnectionString;
}
#endregion
# region "Execute Procedures"
public bool InvokeProcedure(string ProcedureName, SqlTransaction SqlTrn, SqlConnection con)
{
SqlCommand Sqlcmd = new SqlCommand();
try
{
Sqlcmd.CommandType = CommandType.StoredProcedure;
Sqlcmd.Connection = con;
Sqlcmd.Transaction = SqlTrn;
Sqlcmd.CommandText = ProcedureName;
Sqlcmd.Parameters.AddRange(sp.ParameterCollection);
Sqlcmd.ExecuteNonQuery();
return true;
}
catch (Exception e)
{
con.Close();
SqlTrn.Rollback();
throw new Exception("Error Occured :-" + e.Message, e);
}
finally
{
Sqlcmd.Dispose();
}
}
public bool InvokeProcedure(string ProcedureName)
{
SqlCommand Sqlcmd = new SqlCommand();
SqlConnection con = new SqlConnection(strConnection);
try
{
Sqlcmd.CommandType = CommandType.StoredProcedure;
Sqlcmd.Connection = con;
Sqlcmd.CommandText = ProcedureName;
Sqlcmd.Parameters.AddRange(sp.ParameterCollection);
con.Open();
Sqlcmd.ExecuteNonQuery();
return true;
}
catch (Exception e)
{
throw new Exception("Error Occured :-" + e.Message, e);
}
finally
{
con.Close();
Sqlcmd.Dispose();
con.Dispose();
}
}
I'm sure you got the answer to this years ago, but you need to Run All of the ActiveRecord templates, including Struct and Context.
Related
I created a generic method in reading sql statement, but I am having a memory leak whenever I do a select query and using while read.
Sample Query:
public CMItemPackagingType GetItemPackagingType(int itemID)
{
try
{
List<CommandParameter> param = new List<CommandParameter>();
StringBuilder sb = new StringBuilder();
using (BaseConnection db = new BaseConnection())
{
sb.Append("SELECT RATIO, PACKAGING_TYPE_CODE FROM ITEM_PACKAGING_TYPE WHERE ROUND_UP = 0.01 AND ITEM_ID = #itemID");
param.Add(new CommandParameter("#itemID", itemID));
using (var rs = db.ExecSQL(sb.ToString(), param.ToArray()))
{
CMItemPackagingType cmItemInfo = new CMItemPackagingType();
while (rs.Read())
{
CMItemPackagingType list = new CMItemPackagingType();
if (!rs.IsDBNull(0))
list.Ratio = Convert.ToInt32(rs.GetValue(0));
if (!rs.IsDBNull(1))
list.PackagingTypeCode = rs.GetValue(1).ToString();
cmItemInfo.ItemPackagingTypeList.Add(list);
}
return cmItemInfo;
}
}
}
catch (Exception ex)
{
GlobalFramework.HandleException(ex);
}
return null;
}
Generic Reader:
public DbDataReader ExecSQL(string sqlStmt, CommandParameter[] param)
{
List<MySqlParameter> p = ParameterMySql(param);
_mySqlConn = new MySqlConnection(szConnect);
if (_mySqlConn.State == ConnectionState.Open)
{
_mySqlConn.Close();
}
_mySqlConn.Open();
_mySqlComm = new MySqlCommand(sqlStmt, _mySqlConn);
_mySqlComm.Parameters.AddRange(p.ToArray());
MySqlDataReader reader = _mySqlComm.ExecuteReader();
return reader;
}
I'm assuming the BaseConnection is a wrapper around a SqlConnection and _mySqlConn is an instance of BaseConnection. I suspect the issue is that you are opening and closing the connection in ExecSQL and at the same time have a using statement around BaseConnection creating this leak. I would refactor your code with proper placement of using statements to ensure correct disposal of the objects and freeing of resources.
Example
var query = "YOUR QUERY";
using (var connection = new SqlConnection("YOUR CONNECTION STRING"))
{
using (var command = new SqlCommand(query, connection))
{
await connection.OpenAsync();
using (var reader = await command.ExecuteReaderAsync())
{
if (reader != null)
{
while (await reader.ReadAsync())
{
// your logic
}
}
} // reader closed and disposed up here
} // command disposed here
} //connection closed and disposed here
}
Also notice how I'm using the async versions of the ADO.NET methods. Async commands are critical in achieving scale, throughput, and latency.
I recommend you use Dapper over trying to develop a generic data reader and writing all the boilerplate ADO.NET code yourself.
I am working on a program that upload PDF files to FileNet, and was wondering if there is a way to retrieve the GUID without running a SQL Query. I also tried Retrieving a Document (fetchInstance) from https://www.ibm.com/support/knowledgecenter/en/SSNW2F_5.5.0/com.ibm.p8.ce.dev.ce.doc/document_procedures.htm without the new Id part of the code and that did not work.
public class DocIdGenerator implements EventActionHandler {
private static final String DS = "ECMSvcsXA";
private static final String INSERT_SQL = "Insert into dbo.ICNLegalDocID_S (object_id) values (?)";
private static final String SELECT_SQL = "Select DocId From dbo.ICNLegalDocID_S Where object_id = ?";
#Override
public void onEvent(ObjectChangeEvent event, Id subscriptionId)
throws EngineRuntimeException {
// Get the Document object from the event
ObjectStore os = event.getObjectStore();
Id objectId = event.get_SourceObjectId();
PropertyFilter pf = new PropertyFilter();
pf.addIncludeProperty(new FilterElement(null, null, null, "DocumentID", null));
pf.addIncludeProperty(new FilterElement(null, null, null, PropertyNames.VERSION_SERIES, null));
Document sourceDoc = Factory.Document.fetchInstance(os, objectId, pf);
Properties props = sourceDoc.getProperties();
String documentId = props.getStringValue("DocumentID");
VersionSeries vs = sourceDoc.get_VersionSeries();
Id versionSeriesId = vs.get_Id();
if (documentId == null || documentId.isEmpty()) {
// Get the JNDI Context to lookup DataSource and Insert the objectId to get the auto generated docId
Context ctx;
DataSource ds;
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
ctx = new InitialContext();
ds = (DataSource) ctx.lookup(DS);
con = ds.getConnection();
ps = con.prepareStatement(SELECT_SQL);
ps.setString(1, versionSeriesId.toString());
rs = ps.executeQuery();
BigDecimal docId = null;
if (rs.next()) {
// Document Id already exists
docId = rs.getBigDecimal(1);
} else {
// Document Id doesn't exist inert to get it
ps = con.prepareStatement(INSERT_SQL, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, versionSeriesId.toString());
ps.executeUpdate();
rs = ps.getGeneratedKeys();
if (rs.next()) {
docId = rs.getBigDecimal(1);
}
}
props.putValue("DocumentID", docId.toString());
sourceDoc.save(RefreshMode.REFRESH);
} catch (Exception e) {
e.printStackTrace();
if (e instanceof EngineRuntimeException) {
throw (EngineRuntimeException)e;
} else {
ErrorStack es = new ErrorStack("DocIdGeneratorSub", new ErrorRecord[] {new ErrorRecord(e)});
throw new EngineRuntimeException(es);
}
} finally {
close(con, ps, rs);
}
}
}
private void close(Connection con, PreparedStatement ps, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// Ignore
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
// Ignore
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
// Ignore
}
}
}
}
I am not sure that I understand what to you trying to do.
When you create new document instance (Document doc = Factory.Document.newInstance()) and invoke doc.save(Refresh.REFRESH) options, FileNet inserts new DB record for document instance, generate new ID and populate it backward to the document instance on your side.
So, to get Id for new Document you just need to call doc.getId() to get it.
As I understand from your sample, you try to use event handler, If you invoke handler on the event before creation, you don't have any Id at this time, you cant try to handle the event after document creation.
I am new to EF code first approach, what I am trying to do is just inserting a record but somehow the database fails to generate in my SQL Server when my SubmitResult method is executed. I placed a breakpoint at unitOfWork.Save(); and it went through without catching any errors, I assume that if my connection string is invalid it would have thrown an exception. What could possibly be causing this?
Thanks.
[HttpPost]
public JsonResult SubmitResult(String signedRequest, String facebookName, String email, int score, String title)
{
DateTime now = ConstantHelper.GetCurrentTime();
try
{
FacebookSignedRequestUtility fbSignedRequestUtility = new FacebookSignedRequestUtility();
fbData = fbSignedRequestUtility.Parse(FacebookUtility.AppSecret, signedRequest);
Entry entry = new Entry();
entry.Fbuid = fbData.FBUID;
entry.FacebookName = facebookName;
entry.Email = email;
entry.Score = score;
entry.Title = title;
entry.CreatedDateTime = now;
entry.ModifiedDateTime = now;
unitOfWork.EntryRepository.Insert(entry);
unitOfWork.Save();
}
catch (Exception ex)
{
return Json(new { status = "false" });
}
return Json(new { status = "true" });
}
Ok found out that my unitOfWork class has some issues, it works if instantiate my db and save.
AmexContext amc = new AmexContext() ;
amc.SaveChanges();
What is the purpose of using (connection) in the code - please explain me
static void HasRows(SqlConnection connection)
{
using (connection)/// what is this line
{
SqlCommand command = new SqlCommand(
"SELECT CategoryID, CategoryName FROM Categories;",
connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
reader.GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
reader.Close();
}
}
using (connection){
connection.Open();
}
makes sure that connection is closed when the application is done using it.
similar to a Try Catch.
try{
connection.Open();
}
catch{
}
finally{
connection.Dispose();
}
Disposing of the connection is another way of saying closing a connection. An open connection can leak memory and if you have too many it can slow down or freeze up whatever you are connecting to.
the using function closes the connection even after you return something from the class you are in. same as the try catch. it always closes the connection no matter what happens inside the brackets. even if there is an exception that breaks out of the class/application the connection still gets closed
Using
Quote from site:
The using statement allows the programmer to specify when objects that use resources should release them. The object provided to the using statement must implement the IDisposable interface. This interface provides the Dispose method, which should release the object's resources.
I would probably re-write the method to something like the following:
static void HasRows(string connectionString)
{
using (var connection = new SqlConnection(connectionString))
using(var command = new SqlCommand("SELECT CategoryID, CategoryName FROM Categories;",
connection))
{
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
reader.GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
}
}
}
In your original implementation the caller could be at the receiving end of an ObjectDisposedException exception, because the SqlConnection is passed in as a parameter.
I have console application in which I am doing sqldependency. My problem is when I set commandType as Text, it is working fine. But if I use commandType as StoredProcedure, onchange method is calling infinitely.
Please see the code below:
static DataSet myDataSet;
static SqlConnection connection;
static SqlCommand command;
static void Main(string[] args)
{
// Remove any existing dependency connection, then create a new one.
string connstr = "Data Source=XYZ;Initial Catalog=Dev;Integrated Security=True";
string ssql = #"[dbo].[SchedulerPendingControlRequestIDFetch]";
CanRequestNotifications();
SqlDependency.Stop(connstr);
SqlDependency.Start(connstr);
if (connection == null)
connection = new SqlConnection(connstr);
if (command == null)
command = new SqlCommand(ssql, connection);
command.CommandType = CommandType.StoredProcedure;
if (myDataSet == null)
myDataSet = new DataSet();
GetAdvtData();
System.Console.ReadKey();
connection.Close();
}
private static bool CanRequestNotifications()
{
SqlClientPermission permission =
new SqlClientPermission(
PermissionState.Unrestricted);
try
{
permission.Demand();
return true;
}
catch (System.Exception)
{
return false;
}
}
private static void GetAdvtData()
{
myDataSet.Clear();
// Ensure the command object does not have a notification object.
command.Notification = null;
// Create and bind the SqlDependency object to the command object.
SqlDependency dependency = new SqlDependency(command,null,100);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
adapter.Fill(myDataSet, "ControlRequest");
}
}
private static void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
SqlDependency dependency =
(SqlDependency)sender;
dependency.OnChange -= dependency_OnChange;
Console.WriteLine(e.Info.ToString() + e.Source.ToString());
GetAdvtData();
}
My stored Procedure is:
IF OBJECT_ID('SchedulerSirasColcoDetailFetch') IS NOT NULL
DROP PROCEDURE SchedulerSirasColcoDetailFetch
Go
PRINT 'Creating stored procedure SchedulerSirasColcoDetailFetch'
Go
CREATE PROCEDURE [dbo].[SchedulerSirasColcoDetailFetch]
AS
BEGIN
SELECT Colco_Code AS 'CountryCode',Connection_String AS 'Url',Resend_Interval AS 'ResendInterval',
Default_Encoding AS 'Encoding' FROM dbo.SirasColcoDetail
END
If I copy the select statement inside stored procedure as my command text and set the commandType as Text, everything is working fine.
could you please let me know what the issue is????
Thanks a lot in advance.
Mahesh
You're supposed to check the values of the SqlNotificationEventArgs argument. Only if Type is Change and Source is Data where you notified for a data change.
You'll discover that you're not notified for data changes, but for incorrect settings or incorrect query. Your query and connection settings must comply with the requirements specified in Creating a Query for Notifications.