inserting DataTable into DB using DataAdapter does'nt work - insert

I am trying to insert DataTable into a DB table (the DB is on a mobile device - Psion), using a DataAdapter. from some reason, it does not work - when i check the DB table - it simply appears as an empty table...
the code:
>
private void btnCommTables_Click(object sender, EventArgs e)
{
try
{
DataSet ds = WSDanielGroup.Instance._WSDanielGroupToDevice.GetLoadTables();
DataTable DT = ds.Tables["Peer"];
string SelectCMD = "INSERT INTO Peer(ID,PeerID) Values(?,?)";
SqlCeConnection cn = new SqlCeConnection(DBManager.sLocalConnectionString);
SqlCeDataAdapter da=new SqlCeDataAdapter();
da.InsertCommand = new SqlCeCommand(SelectCMD, cn);
cn.Open();
da.InsertCommand.Parameters.Add("#ID", SqlDbType.Int,4,"ID");
da.InsertCommand.Parameters.Add("#PeerID", SqlDbType.NVarChar,50, "PeerID");
int numRows = da.Update(DT);
}

One possible explanation is that your DataTable doesn't have the correct RowVersions. The DataAdapter will only update rows that have been changed in the table. If you get it from somewhere else, it thinks everything's OK and nothing needs to be updated (rows not marked "dirty"). More info here.

Related

How to set cell value using rowupdating event before query execution C#?

I am using table adapter in my WinForms application to load data from database to gridview. Things work fine except I need to set one field value to be updated too in the database.
Here is my code:
//Fill dataset from database:
attendanceTypeTableAdapter.Fill(dsDataset.attendanceType);
//add rowUpdating event
attendanceTableAdapter.Adapter.RowUpdating += new OleDbRowUpdatingEventHandler(tableAdapter_RowUpdating);
Set modifiedBy field before query executed against database
private void tableAdapter_RowUpdating(object sender, OleDbRowUpdatingEventArgs e)
{
if (e.Status == UpdateStatus.Continue && e.StatementType == StatementType.Update)
{
//set modifiedBy field to current userId
e.Row["modifiedBy"] = globals.userId;
e.Row.AcceptChanges();
}
}
'modifiedBy' field using above code appears in the gridview but unfortunately does not get updated in the database!
What am I missing here?

why i can't edit anything in my DataGridView?

I got this problem. I have a DataGridView with a DataSource that is a Linq query, and when I show the data from my database in the DataGridView, I can't edit anything.
What's the problem?
Here's my code.
private void btMau_Click(object sender, EventArgs e)
{
var lst = from list in db.Maus
join dt in db.DiaTangs on list.IDDiaTang equals dt.IDDiaTang
select new
{
list.IDMau,
list.IDHoKhoan,
list.Lop,
list.BeDayMau,
list.DoSauMau,
dt.TenDiaTang,
dt.MoTa
};
dgv.DataSource = lst;
dgv.ContextMenuStrip = contextMenuStrip2;
check = "Mau";
}
Sorry for my bad english!
PS: dgv is DataGridView
currently your variable is read only. You can fix it by
var lst = (from list in db.Maus
join dt in db.DiaTangs on list.IDDiaTang equals dt.IDDiaTang
select new
{
list.IDMau,
list.IDHoKhoan,
list.Lop,
list.BeDayMau,
list.DoSauMau,
dt.TenDiaTang,
dt.MoTa
}).ToList();
For more details and example, please see this page

JDBC update prepared statement not showing updates

I have two JDBC SQL prepared statements in the program to UPDATE tables (different areas of program). When I run the statement, I can see the updates in MySQL when I query the table. So I know the update is happening. However, I have a table connected to the DB in the program that does not show the updated results unless I stop running the program and restart it. Then the updates show in the table. I have other prepared statements that use INSERT INTO and these changes show up right away in the tables (I don't have to stop-restart my program). I don't know if the problem lies in the UPDATE, or in my code (the usual culprit), or some setting I have wrong. I think I might be passing things wrong between method calls. This is part of what it does: I have an income table, the user creates a new income listing, and part of that listing gets sent to a FUNDS table (with the UPDATE statement) and another part gets sent to an INCOME table (with the INSERT INTO statement). Here is the code, thanks for help and suggestions!
//Get user info
Income income = new Income();
Funds fund = new Funds();
income.setIncomeName(jTextField10.getText());
String budgetAmt = jTextField11.getText();
BigDecimal bAmt = new BigDecimal(budgetAmt);
income.setAmount(bAmt);
income.setDescription(jTextArea3.getText());
String iDate = jTextField12.getText();
Date date = new SimpleDateFormat("MM-dd-yy", Locale.ENGLISH).parse(iDate);
java.util.Date utilDate = date;
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
income.setDateReceived(sqlDate);
s = (String)jList10.getSelectedValue().toString();
income.setFundAllocation(s);
// Send info to be processed in FUND table with UPDATE - start of problem area
FundsSvcJDBCImpl fundImpl = new FundsSvcJDBCImpl();
Funds calculateFundAmt = fundImpl.calculateFundAmt(fund, income);
// Send info to be process in INCOME table - this part works
IncomeSvcJDBCImpl budgetImpl = new IncomeSvcJDBCImpl();
Income addIncome = budgetImpl.addIncome(income);
//This is the part of the FundsSvcJDBCImpl that uses the UPDATE statement
public Funds calculateFundAmt (Funds fund, Income income) throws Exception {
Statement stmt = null;
int max = 0;
BigDecimal fundTotal = new BigDecimal(0);
Connection conn = getConnection();
try{
stmt = conn.createStatement();
String sql1 = "SELECT sum(Amount) As fundTotal FROM funds WHERE FundsName = ?";
PreparedStatement pstmt1 = conn.prepareStatement(sql1);
pstmt1.setString(1, income.getFundAllocation());
ResultSet rs2 = pstmt1.executeQuery();
while(rs2.next()){
fundTotal = fundTotal.add(rs2.getBigDecimal("fundTotal"));
}
fundTotal = fundTotal.add(income.getAmount());
String sql2 = "UPDATE funds SET Amount = ? WHERE FundsName = ?";
PreparedStatement pstmt = conn.prepareStatement(sql2);
pstmt.setBigDecimal(1, fundTotal);
pstmt.setString(2, income.getFundAllocation());
pstmt.executeUpdate();
}
catch (Exception e){
throw e;
}
finally {
if (conn != null){
conn.close();
stmt.close();
}
}
return fund;
}

Custom column in LinqServerModeDataSource

I have table in my database names User with fields:
Id
FirstName
LastName
LoginName
Now I would like to present this table in ASPxGridView using LinqServerModeDataSource.
What I did is :
<dxdtlnq:LinqServerModeDataSource ID="LinqServerModeDataSource1" runat="server" OnSelecting="LinqServerModeDataSource1_OnSelecting"
ContextTypeName="MyContext" EnableDelete="True"
EnableInsert="True" EnableUpdate="True" TableName="Users" >
</dxdtlnq:LinqServerModeDataSource>
protected void LinqServerModeDataSource1_OnSelecting(object sender, LinqServerModeDataSourceSelectEventArgs e)
{
MyContext context = new MyContext();
var qry = from s in context.Users select s;
e.QueryableSource = qry;
}
That works great with my ASPxGridView. I can display data, insert and delete but now I would like to have additional column UserName which is FirstName + LastName.
So I did something like that:
Added appropriate column to my ASPxGridView (FieldName = "UserName")
and modified OnSelecting handler:
protected void LinqServerModeDataSource1_OnSelecting(object sender, LinqServerModeDataSourceSelectEventArgs e) {
KozuModelDataContext context = new MyContext();
var qry = (from s in context.Substitutions
select new
{
Id = s.Id,
FirstName = s.FirstName,
LastName = s.LastName,
LoginName = s.LoginName,
UserName = s.FirstName + " " + s.LastName,
}).AsQueryable();
e.KeyExpression = "Id";
e.QueryableSource = qry;
}
Now data in the grid is displayed buyt when I want to insert or edit data fields cannot be filled, textboxes doesnt respond in inserting form I cant type in any text.
Is there any solution for inserting and editing data in this manner ?
Thanks for help
I have tried to reproduce this issue and see this behavior. To be able to edit data using this approach, I suggest that you do the following:
1) Handle the ASPxGridView.CellEditorIntitialize event and set the e.Editor.ReadOnly property to false. This will allow the end-user to modify data in the EditForm editors;
2) Handle the ASPxGridView.RowUpdating (RowInserting) event and update data manually. Also, you should set the e.Cancel parameter to true (to prevent the grid from updating data itself) and also call the GridView's CancelEdit method to close the EditForm.
I should also mention that there is no need to fetch data for the UserName from the DB. This can be done using the ASPxGridView's CustomColumnDisplayText event handler:
protected void ASPxGridView1_CustomColumnDisplayText(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewColumnDisplayTextEventArgs e) {
if(e.Column.FieldName == "") {
object[] values = ASPxGridView1.GetRowValues(e.VisibleRowIndex, new string[] { "FirstName", "LastName" }) as object[];
e.DisplayText = values[0].ToString() + " " + values[1].ToString();
}
}
If this approach works for you, you can avoid using the Selecting event and thus set the LinqServerModeDataSource's TableName. This will allow you to provide the data editing feature not using the approach I explained above.

Auditing in Entity Framework

After going through Entity Framework I have a couple of questions on implementing auditing in Entity Framework.
I want to store each column values that is created or updated to a different audit table.
Right now I am calling SaveChanges(false) to save the records in the DB(still the changes in context is not reset). Then get the added | modified records and loop through the GetObjectStateEntries. But don't know how to get the values of the columns where their values are filled by stored proc. ie, createdate, modifieddate etc.
Below is the sample code I am working on it.
// Get the changed entires( ie, records)
IEnumerable<ObjectStateEntry> changes = context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified);
// Iterate each ObjectStateEntry( for each record in the update/modified collection)
foreach (ObjectStateEntry entry in changes)
{
// Iterate the columns in each record and get thier old and new value respectively
foreach (var columnName in entry.GetModifiedProperties())
{
string oldValue = entry.OriginalValues[columnName].ToString();
string newValue = entry.CurrentValues[columnName].ToString();
// Do Some Auditing by sending entityname, columnname, oldvalue, newvalue
}
}
changes = context.ObjectStateManager.GetObjectStateEntries(EntityState.Added);
foreach (ObjectStateEntry entry in changes)
{
if (entry.IsRelationship) continue;
var columnNames = (from p in entry.EntitySet.ElementType.Members
select p.Name).ToList();
foreach (var columnName in columnNames)
{
string newValue = entry.CurrentValues[columnName].ToString();
// Do Some Auditing by sending entityname, columnname, value
}
}
Here you have two basic options:
Do it at the database level
Do it in the c# code
Doing it at the data base level, means using triggers. In that case there is no difference if you are using enterprise library or another data access technology.
To do it in the C# code you would add a log table to your datamodel, and write the changes to the log table. When you do a save changes both the changes to the data and the information which you wrote to the log table would be saved.
Are you inserting the new record using a stored proc? If not (i.e. you are newing up an object, setting values, inserting on submit and then saving changes the new object id will be automatically loaded into the id property of the object you created. If you are using a stored proc to do the insert then you need to return the ##IDENTITY from the proc as a return value.
EX:
StoreDateContext db = new StoreDataContext(connString);
Product p = new Product();
p.Name = "Hello Kitty Back Scratcher";
p.CategoryId = 5;
db.Products.Add(p);
try
{
db.SaveChanges();
//p.Id is now set
return p.Id;
}
finally
{
db.Dispose;
}

Resources