I have a method here I created for homework. I believe it works, and I want to test it to work. So here's the method:
public static bool UpdatePerson (Personnel person, out string result)
{
result = "update not successful";
bool flag = false;
System.Data.SqlClient.SqlCommand updatePerson = new System.Data.SqlClient.SqlCommand();
updatePerson.Connection = Data.con;
//updatePerson.CommandType = CommandType.StoredProcedure;
SqlParameter p1 = new SqlParameter("perFirstName", person.First);
SqlParameter p2 = new SqlParameter("perMiddleName", person.Middle);
SqlParameter p3 = new SqlParameter("perLastName", person.Last);
SqlParameter p4 = new SqlParameter("ID", person.PersonnelID);
updatePerson.Parameters.Add(p1);
updatePerson.Parameters.Add(p2);
updatePerson.Parameters.Add(p3);
updatePerson.Parameters.Add(p4);
updatePerson.CommandText = "Update tblPersonnel Set perFirstName = " + p1 + " perMiddleName = " + p2 + " perLastName = " + p3 + "Where ID = " + p4;
try
{
Data.con.Open();
updatePerson.ExecuteNonQuery();
result = "Update Successful";
flag = true;
}
catch (Exception ex)
{
result = ex.Message;
}
finally
{
if (Data.con.State == System.Data.ConnectionState.Open)
Data.con.Close();
}
return flag;
}
Now here's the test coding:
using MovieLibrary;
namespace Test
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string result = " ";
MovieLibrary.Personnel update = MovieLibrary.Personnel.UpdatePerson(MovieLibrary.Personnel, out result);
if (update != null)
this.Label1.Text = result;
}
}
The only thing giving me a problem is inserting data in the parameters. This gives me an error saying MovieLibrary.Personnel is a type and does not belong there.
You need to pass an instance of Personnel. Currently, you're using the type's name as an argument.. which you cannot do. Also.. your method returns bool.. not a Personnel object.
Hopefully this makes it more clear. This is what you have, which is wrong:
MovieLibrary.Personnel update =
MovieLibrary.Personnel.UpdatePerson(MovieLibrary.Personnel, out result);
// ^^^^^^^^^^^^^^^^^^^^^^ Wrong
However, this is what you need:
Personnel p = new Personnel();
// set properties here
// it returns bool
bool updated =
MovieLibrary.Personnel.UpdatePerson(p, out result);
// ^^ Right.. an instance
Also, you are returning bool, but also have an out parameter for the result. Consider making it return the result (or deciding what to do based on the boolean return value.. or possibly let the exception get thrown out of the method).
Related
I'm having hard time figuring out what the problem is. I'm trying to make sort of process monitor which loads processes list, ID, username of owner,memory usage and description.. and this error is giving me really big headache.
private void Button1_Click(object sender, EventArgs e)
{
Process[] procList = Process.GetProcesses();
foreach (Process process in procList)
{
// get status
string status = (process.Responding == true ? "Responding" : "Not responding");
// get username and description
string query = "SELECT * FROM Win32_Process WHERE ProcessID = " + process.Id;
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection processList = searcher.Get();
dynamic response = new ExpandoObject();
response.Description = "";
response.Username = "Unknown";
foreach (ManagementObject obj in processList)
{
// get username
string[] argList = new string[] { string.Empty, string.Empty };
int returnValue = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
if (returnValue == 0)
response.Username = argList[0];
if (obj["ExecutablePath"] != null)
{
try
{
FileVersionInfo info = FileVersionInfo.GetVersionInfo(obj["ExecutablePath"].ToString());
response.Description = info.FileDescription;
}
catch { }
}
}
// get memory usage
int memsize = 0; // memsize in Megabyte
PerformanceCounter PC = new PerformanceCounter();
PC.CategoryName = "Process";
PC.CounterName = "Working Set - Private";
PC.InstanceName = process.ProcessName;
memsize = Convert.ToInt32(PC.NextValue()) / (int)(1024);
memsize = (memsize / 1024);
PC.Close();
PC.Dispose();
ListViewItem item = new ListViewItem();
item.Text = process.Id.ToString();
item.SubItems.Add(process.ProcessName);
item.SubItems.Add(status);
item.SubItems.Add(response.Username);
item.SubItems.Add(memsize.ToString() + " MB");
item.SubItems.Add(response.Description);
listView1.Items.Add(item);
}
}
When i try debugging the program, it outputs few of them without any problem, (see here -> https://i.imgur.com/D4ftBgb.png) and then error shows up -> https://i.imgur.com/m1R90hz.png
Because you use dynamic, method overload resolution is delayed until runtime. You have a null response.Username or response.Description, so the dynamic runtime doesn't know which overload to call. Compare:
public class Test
{
public static void Main()
{
dynamic bar = null;
try
{
Foo(bar);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
private static void Foo(string f) { }
private static void Foo(int? o) { }
}
This throws the same exception, because both overloads can accept a null, and there is no further type information present.
To resolve this, either specify the overload explicitly by casting to string:
Foo((string)bar);
Or in your case, SubItems.Add((string)response.Username).
Or simply don't use dynamic to stuff your variables in, but keep them both declared as separate variables: string description = "", username = "".
The type of both your response.Username and response.Description is dynamic. The ListViewSubItemCollection.Add() can't decide which overload to use, therefore, you need to convert them to string.
Try the following:
string username = Convert.ToString(response.Username);
string description = Convert.ToString(response.Description);
ListViewItem item = new ListViewItem();
item.Text = process.Id.ToString();
item.SubItems.Add(process.ProcessName);
item.SubItems.Add(status);
item.SubItems.Add(username);
item.SubItems.Add(memsize.ToString() + " MB");
item.SubItems.Add(description);
listView1.Items.Add(item);
The best long term solution is to remove your use of dynamic and use an explicit class with Description and Username properties.
The most direct fix is to change:
response.Description = info.FileDescription;
to:
response.Description = info.FileDescription ?? "";
Why is that necessary (the ?? "")? It will allows the overload resolution to work correctly since Description will never be null. The reason why it doesn't work when null is that a null property of an ExpandoObject has no type associated with it. This is different to a normal class whereby the compiler knows that the type of the property is string.
I have an application currently fully operational using OracleDB.Recently, I converted my OracleDB into PostgreSQL and I am facing a weird problem.Whenever I try to access my procedure of PostGreSQL through application, sometimes it works perfectly and sometimes does not.It gives an error saying that "this procedure(my procedure name) does not exist,while it exists in the database and works perfectly with pgAdmin query tool. I am really confused,please help me out. Here I am giving one of my sample procedure below and attaching error log too.
CREATE OR REPLACE FUNCTION sylvia.pro_occupation_add(
p_occupationid bigint,
p_occupationname text,
p_occupationdetails text)
RETURNS void
LANGUAGE 'plpgsql'
AS $BODY$
begin
insert into sylvia.occupation (occupationid,occupationname,occupationdetails)
values (p_occupationid, p_occupationname, p_occupationdetails);
end;
$BODY$;
C# code :
private DataSet _createOccupation(DataSet inputDS)
{
ErrorDS errDS = new ErrorDS();
EmployeeHistDS employeeHistDS = new EmployeeHistDS();
DBConnectionDS connDS = new DBConnectionDS();
//extract dbconnection
connDS.Merge(inputDS.Tables[connDS.DBConnections.TableName], false, MissingSchemaAction.Error);
connDS.AcceptChanges();
//create command
NpgsqlCommand cmd = new NpgsqlCommand();
cmd.CommandText = "PRO_OCCUPATION_ADD";
cmd.CommandType = CommandType.StoredProcedure;
employeeHistDS.Merge(inputDS.Tables[employeeHistDS.Occupation.TableName], false, MissingSchemaAction.Error);
employeeHistDS.AcceptChanges();
foreach (EmployeeHistDS.OccupationRow row in employeeHistDS.Occupation)
{
long genPK = IDGenerator.GetNextGenericPK();
if (genPK == -1)
{
return UtilDL.GetDBOperationFailed();
}
cmd.Parameters.Add("p_OccupationId", genPK);
cmd.Parameters.Add("p_OccupationName", row.OccupationName);
if (!row.IsOccupationDetailsNull()) cmd.Parameters.Add("p_OccupationDetails", row.OccupationDetails);
else cmd.Parameters.Add("p_OccupationDetails", DBNull.Value);
bool bError = false;
int nRowAffected = -1;
nRowAffected = ADOController.Instance.ExecuteNonQuery(cmd, connDS.DBConnections[0].ConnectionID, ref bError);
if (bError == true)
{
ErrorDS.Error err = errDS.Errors.NewError();
err.ErrorCode = ErrorCode.ERR_DB_OPERATION_FAILED.ToString();
err.ErrorTier = ErrorTier.ERR_TIER_DL.ToString();
err.ErrorLevel = ErrorLevel.ERR_LEVEL_SEVER.ToString();
err.ErrorInfo1 = ActionID.ACTION_OCCUPATION_ADD.ToString();
errDS.Errors.AddError(err);
errDS.AcceptChanges();
return errDS;
}
}
errDS.Clear();
errDS.AcceptChanges();
return errDS;
}
public int ExecuteNonQuery(NpgsqlCommand cmdInsertUpdateDelete, int connectionID, ref bool bError)
{
CConnectionInfo connInfo = (CConnectionInfo)this.m_hashConn[connectionID];
if (connInfo == null)
{
AppLogger.LogWarning("Connection ID '" + connectionID + "' does not exist in connection pool.\nCould not execute ExecuteNonQuery method.");
bError = true;
return -1;
}
NpgsqlConnection conn = connInfo.m_Conn_PG;
NpgsqlTransaction tx = connInfo.m_Tx_PG;
cmdInsertUpdateDelete.Connection = conn;
cmdInsertUpdateDelete.Transaction = tx;
try
{
bError = false;
return cmdInsertUpdateDelete.ExecuteNonQuery();
}
catch (Exception ex)
{
WriteErrorLog(ex, connectionID);
AppLogger.LogFatal("Error executing ExecuteNonQuery method.\n" + cmdInsertUpdateDelete.CommandText, ex);
invalidateConnectionID(connectionID);
bError = true;
return -1;
}
finally
{
cmdInsertUpdateDelete.Transaction = null;
cmdInsertUpdateDelete.Connection = null;
}
}
Error Log
I have a web method function has checks if a name exists in the database but I am getting the error:
Error 114 'lookups_Creditor.CheckIfNameExists(string)': not all code
paths return a value
Here is the web method:
[WebMethod]
public static bool CheckIfNameExists(string Name)//error on this line
{
try
{
Creditor.CheckIfNameCreditorExists(Company.Current.CompanyID, Name);
}
catch (Exception ex)
{
}
}
And here is the search function for the sql:
public static string CheckIfNameCreditorExists(int CompanyID, string Name)
{
DataSet ds = new DataSet();
string accNo = "";
string sql = "proc_CheckIfACCreditorExists";
string query = "SELECT c.* " +
" FROM Creditor c " +
" WHERE c.Company_ID = " + CompanyID + " AND c.Name LIKE '" + Name + "' ";
DataTable dt = new DataTable();
using (MySql.Data.MySqlClient.MySqlDataAdapter adapter = new MySql.Data.MySqlClient.MySqlDataAdapter(query, DataUtils.ConnectionStrings["TAT"]))
{
adapter.SelectCommand.CommandType = CommandType.Text;
adapter.SelectCommand.CommandText = query;
adapter.Fill(dt);
if (dt.Rows.Count > 0)
{
accNo = Convert.ToString(dt.Rows[0]["AccoutCode"]);
}
}
return accNo;
}
I am trying to create a method that searches for the name in the database. If the name exists, then return the account code associated with that name. I will the display a message on the screen telling the user that the name already exists on the account ABC.
[WebMethod]
public static bool CheckIfNameExists(string Name)//error on this line
{
bool Result = false;
try
{
Result = Creditor.CheckIfNameCreditorExists(Company.Current.CompanyID, Name) != "";
}
catch (Exception ex)
{
}
return Result
}
You have written the return type as Bool and you are not returning anything.
If you don't have anything to return then just make that return type to Void.
By the method name it indicates you should return either "True" or "False".
The error just indicates that, you should return something when you have a return type other than void in your methods.
Your method is supposed to return bool, yet you don't return anything.
You need to rewrite it something like this:
[WebMethod]
public static bool CheckIfNameExists(string Name)
{
bool res = false;
try
{
// Check your string result if it's null or empty
// and store the result in local variable
res = !string.IsNullOrEmpty(Creditor.CheckIfNameCreditorExists(Company.Current.CompanyID, Name));
}
catch (Exception ex)
{
// Do your handling here
}
return res;
}
My code as follows:
namespace EntityDAO
{
public static class StudentDAO
{
public static Boolean AddStudent(StudentDTO oDto)
{
string str =System.Configuration.ConfigurationManager.AppSettings["myconn"];
SqlConnection oconnection = new SqlConnection(str);
oconnection.Open();
try
{
string addstring = "insert into STUDENT(ID,NAME)values('"
+ oDto.ID + "','"
+ oDto.NAME + "')";
SqlCommand ocommand = new SqlCommand(addstring,oconnection);
ocommand.ExecuteNonQuery();
return true;
}
catch
{
return false;
}
finally
{
oconnection.Close();
}
but when I run this program ,an error message has been occured and the error message for oconnection.Open(); and the message is 'InvalidOperationException'(Instance failure).I have tried many times to solve this problem but i did't overcome this problem.so please,anyone help me.
The following is not proposed as a complete solution to your problem, but should help you figure it out:
namespace EntityDAO
{
public static class StudentDAO
{
public static Boolean AddStudent(StudentDTO oDto)
{
var str = ConfigurationManager.AppSettings["myconn"];
using (var oconnection = new SqlConnection(str))
{
oconnection.Open();
try
{
var addstring = string.Format(
"insert into STUDENT(ID,NAME)values('{0}','{1}')", oDto.ID, oDto.NAME);
using (var ocommand = new SqlCommand(addstring, oconnection))
{
ocommand.ExecuteNonQuery();
}
return true;
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
return false;
}
}
}
}
}
Don't ever hide exceptions from yourself. Even if the caller of this code wants true or false, make sure you log the details of the exception.
Also, what AYK said about SQL Injection. I'm entering this as CW, so if someone has more time than I do, they should feel free to edit to use parameters.
My issue is the following: i'm trying to build a function to which i could pass a list of items, which would then go to the db with each of those items and update them. I believe the issue is within the way datacontexts are being used but i cannot figure out this issue.
Here is my function that builds the list of items that were changed:
protected void btnSave_Click(object sender, EventArgs e)
{
List<AFF_CMS_FMA> fmasToSave = new List<AFF_CMS_FMA>();
AFF_CMS_FMA newFmaItem = new AFF_CMS_FMA();
foreach (AFF_CMS_FMA fmaItem in FmaLib.fetchAllActiveAssetsInFMA())
{
if (fmaItem.SortOrder != Convert.ToInt32(Request.Form["fmaItem_" + fmaItem.ID + "_SortOrder"]))
{
newFmaItem = fmaItem;
newFmaItem.Name = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_Name"]);
newFmaItem.AssetID = Convert.ToInt32(Request.Form["fmaItem_" + fmaItem.ID + "_AssetID"]);
newFmaItem.SortOrder = Convert.ToInt32(Request.Form["fmaItem_" + fmaItem.ID + "_SortOrder"]);
newFmaItem.ImagePathEn = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_ImagePathEn"]);
newFmaItem.ImagePathCh = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_ImagePathCh"]);
newFmaItem.StartDate = DateTime.Parse(SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_StartDate"]));
newFmaItem.EndDate = DateTime.Parse(SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_EndDate"]));
newFmaItem.ClickToUrl = SecurityLib.SqlSafeString(Request.Form["fmaItem_" + fmaItem.ID + "_ClickToUrl"]);
fmasToSave.Add(newFmaItem);
}
}
FmaLib.saveEditedFmas(fmasToSave);
}
here is the function that the foreach loops calls to get all the items that are in the db:
public static List<AFF_CMS_FMA> fetchAllActiveAssetsInFMA()
{
List<AFF_CMS_FMA> results = null;
using (fmaDataContext db = new fmaDataContext())
{
using (TransactionScope ts = new TransactionScope())
{
try
{
if (HttpContext.Current.Cache["fmaActiveList"] == null)
{
db.LoadOptions = loadAll;
results = clsCompiledQuery.getAllActiveFmas(db).ToList();
HttpContext.Current.Cache["fmaActiveList"] = results;
}
else
results = (List<AFF_CMS_FMA>)HttpContext.Current.Cache["fmaActiveList"];
ts.Complete();
}
catch (Exception ex)
{ Transaction.Current.Rollback(); }
}
return results;
}
}
here are the queries being used:
protected static class clsCompiledQuery
{
public static Func<DataContext, IOrderedQueryable<AFF_CMS_FMA>>
getAllActiveFmas = CompiledQuery.Compile((DataContext db)
=> from fma in db.GetTable<AFF_CMS_FMA>()
where fma.IsArchived == false
orderby fma.SortOrder ascending
select fma);
public static Func<DataContext, int,IQueryable<AFF_CMS_FMA>>
getFmaById = CompiledQuery.Compile((DataContext db, int ID)
=> from fma in db.GetTable<AFF_CMS_FMA>()
where fma.ID == ID
select fma);
}
and finally this were im trying to get the save to happen to the db but no exeptions are throwns, yet the db does not change
public static bool saveEditedFmas(List<AFF_CMS_FMA> fmaToSaveList)
{
using (fmaDataContext db = new fmaDataContext())
{
using (TransactionScope ts = new TransactionScope())
{
try
{
foreach (AFF_CMS_FMA fmaItemToSave in fmaToSaveList)
{
AFF_CMS_FMA fmaItemToUpdate = clsCompiledQuery.getFmaById(db, fmaItemToSave.ID).ToList()[0];
fmaItemToUpdate = fmaItemToSave;
db.SubmitChanges();
}
return true;
}
catch (Exception ex)
{
Transaction.Current.Rollback();
return false;
}
}
}
}
I have checked and the table does contain a primary key in the designer. If i do the save from the btnSave_click function by passing a datacontext to the fetchAllActiveAssetsInFMA() then doing submitchanges on that context it works .. but im trying to abstract that from there.
thanks all in advance
Your not calling ts.Complete in function saveEditedFmas.
Also I would recommend calling db.SubmitChanges(); outside of the for loop. And why do you have a transaction in function fetchAllActiveAssetsInFMA? It's only fetching data right? And I'm not quite sure whats happening inside the for loop in save function, looks strange.
I think you should map the properties from fmaItemToSave to fmaItemToUpdate
foreach (var fmaItemToSave in fmaToSaveList)
{
var fmaItemToUpdate = clsCompiledQuery.getFmaById(db, fmaItemToSave.ID).First();
fmaItemToUpdate.Name = fmaItemToSave.Name;
fmaItemToUpdate.AssetID = fmaItemToSave.AssetID;
//And the rest of the properties
}
db.SubmitChanges();