linq - inserting new data replaces existing data on database.why? - c#

When I call the datacontextInstance.Insertonsubmit() and datacontextinstance.submitChanges(), it clears all the existing data in the database before inserting the new data.
How do I perform a real insert operation?
I want to add new data to the existing table without clearing out the existing data.
Thanks
Edit:
Here's my test code which i tried...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
DataClasses1DataContext entities = new DataClasses1DataContext();
for (int i = 1; i <= 100; i++)
{
textdata dt = new textdata();
dt.id = i;
dt.ipaddress = "172.168.3.2";
dt.pcname = "testusr";
dt.publicip = "test pub ip";
dt.username = "testusr";
dt.textdata1 = "Some DATA";
dt.dttime = DateTime.Now;
entities.textdatas.InsertOnSubmit(dt);
entities.SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict);
}
foreach (textdata dtdata in entities.textdatas)
{
Console.WriteLine(dtdata.dttime.Value.ToString());
}
Console.ReadLine();
}
}
}
I do change the loop from 100 to 200,300 to 400 etc before i run my app. But,the new records appear in the database and the old records are gone.
Edit again:
Here's my App.Config...
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="ConsoleApplication2.Properties.Settings.Database1ConnectionString"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>

Can you just post your insert method? I think the problem is from your code not VS2010.

Unless you've also retrieved all the data and called DeleteOnSubmit for each of the retrieved elements, it shouldn't be deleting any data when you do an InsertOnSubmit. Items that are inserted result in SQL insert statements being generated when you call SubmitChanges. The only way that I know of to get a delete statement is to call DeleteOnSubmit. Perhaps, you are thinking that you need to remove the items from the table before calling submit changes to reduce the amount of data pushed back to the server. This isn't correct. Only the new or changed data will be sent back -- and calling DeleteOnSubmit will force the data to be removed when SubmitChanges is called.

My guess is that id is the key in database, but it is not autogenerated.
so when you create your new entities and assign them keys that already exist in db - db entries just get overriden by new ones.

Related

C# Insert into database, no error and data is not inserted into database

I'm attempting to insert some data into my local SQL database. The command seems to run successfully and I'm not getting any errors, but for some reason the data is not being inserted into the database. Have I forgotten something?
public void RegisterUser(string fName, string lName, string email, string password)
{
string conStr = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString;
using (SqlConnection openCon = new SqlConnection(conStr))
{
string saveUser = "INSERT into Users (firstName,lastName,email,password,isAdmin) VALUES (#firstName,#lastName,#email,#password,#isAdmin)";
using (SqlCommand querySaveUser = new SqlCommand(saveUser))
{
querySaveUser.Connection = openCon;
querySaveUser.Parameters.AddWithValue("#firstName", fName);
querySaveUser.Parameters.AddWithValue("#lastName", lName);
querySaveUser.Parameters.AddWithValue("#email", email);
querySaveUser.Parameters.AddWithValue("#password", password);
querySaveUser.Parameters.AddWithValue("#isAdmin", 1);
openCon.Open();
querySaveUser.ExecuteNonQuery();
}
}
}
Connection String:
<connectionStrings>
<add name="DatabaseConnectionString" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\App_Data\Database.mdf;Integrated Security=True;"
providerName="System.Data.SqlClient" />
update:
SOLVED! I was trying to output to another directory for some reason. Ended up recreating the database which solved the issue.
Do
int affected = querySaveUser.ExecuteNonQuery();
and set a debug point and watch affected value.
According to MSDN "If a rollback occurs, the return value is also -1."
In case you are debugging a copy of your DB is created in bin/Debug folder, thus you might be checking different DB. Check this - https://visualstudiomagazine.com/blogs/tool-tracker/2012/05/dealing-with-local-databases-or-why-your-updates-dont-stick.aspx
I check your code and its working fine in my system but i have changed your connection string so please modified your connection string as mine then check i hope your problem solved
public void RegisterUser(string fName, string lName, string email, string password)
{
string conStr = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString;
using (SqlConnection openCon = new SqlConnection(conStr))
{
string saveUser = "INSERT into Users (firstName,lastName,email,password,isAdmin) VALUES (#firstName,#lastName,#email,#password,#isAdmin)";
using (SqlCommand querySaveUser = new SqlCommand(saveUser))
{
querySaveUser.Connection = openCon;
querySaveUser.Parameters.AddWithValue("#firstName", fName);
querySaveUser.Parameters.AddWithValue("#lastName", lName);
querySaveUser.Parameters.AddWithValue("#email", email);
querySaveUser.Parameters.AddWithValue("#password", password);
querySaveUser.Parameters.AddWithValue("#isAdmin", 1);
openCon.Open();
querySaveUser.ExecuteNonQuery();
}
}
}
Connection String: web.config
<connectionStrings>
<add name="DatabaseConnectionString" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Database.mdf; Initial Catalog=Database.mdf; Integrated Security=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
It might help someone looking for Entity Framework Core or ASP.NET Zero related solution.
In my case I was using ASP.NET Zero boiler plate templates for ASP.NET Core and it was not inserting into the database. After a few minutes exploration, I found out that ASP.NET Zero does not immediately execute the ef queries on db rather it inserts rows at end of the unit of work.
Usually, it fails to insert if there is an exception it will log that to Logs table, you can see the latest logs with exceptions if they were failed.
If you want to execute the queries immediately, you can force it to save changes by calling the SaveChanges() method like this:
await CurrentUnitOfWork.SaveChangesAsync();

How to minimise OleDbDataAdapter time to fetch data from remote database

My Windows form Application contains OleDbDataAdapter, it is consuming longer time to fetch data from remote DB. It is not able to retrieve/Hold table data like 5000 rows(Application gets struck). Here is my code.
environments = ConfigurationManager.GetSection("Environment") as NameValueCollection;
string strConnString = environments[envs];
conn = new OleDbConnection(strConnString);
conn.Open();
OleDbDataAdapter objDa = new OleDbDataAdapter("select * from tblABC", conn);
DataSet ds1 = new DataSet();
objDa.Fill(ds1);
dataGridView1.DataSource = ds1.Tables[0];
Environment section is configured in app.config file :
<configuration>
<configSections>
<section name ="Environment" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<Environment>
<add key ="CIT" value ="Password=pwd123;User ID=abc123;Data Source=db1;Persist Security Info=True;Provider=MSDAORA"/>
<add key ="SIT" value ="Password=pwd234;User ID=abc234;Data Source=db2;Persist Security Info=True;Provider=MSDAORA"/>
<add key ="UAT" value ="Password=pwd345;User ID=abc345;Data Source=db3;Persist Security Info=True;Provider=MSDAORA"/>
</Environment>
</configuration>
It would be greatful if someone could suggest better approach/mechanism with code.
Did you try to work with threads. create a sub function somewhere in your program like below
public void dataPullingThread(){
try{
//your connection code goes here like below//
environments = ConfigurationManager.GetSection("Environment") as NameValueCollection;
string strConnString = environments[envs];
conn = new OleDbConnection(strConnString);
conn.Open();
OleDbDataAdapter objDa = new OleDbDataAdapter("select * from tblABC", conn);
DataSet ds1 = new DataSet();
objDa.Fill(ds1);
dataGridView1.DataSource = ds1.Tables[0];
conn.Close();
}
catch (Exception e){
}
}
//call your thread from desired location in program///
using System.Threading;
Thread thread = new Thread (new ThreadStart(dataPullingThread));
thread.start;
//Your application will continuously run; however, the data will appear when ever the thread auto kills itself. You can boost the speed if you create more then one thread. That means each thread selecting different rows of the database, I hope this information will help you//
Here are some general ADO.NET optimization tricks:
Instead of doing SELECT *, please ensure that you really need all the fields. The problem is that many unused field values might be retrieved and it consume resources.
For example, do SELECT Field1, Field2, Field3 instead of SELECT * if your table contains more than those three fields.
Stick to the following connection open/close pattern:
Example:
using(var con = new OleDbConnection(strConnString))
{
con.Open();
...
con.Close();
}
So the connection is closed even if wrong things happens, and the connection pooling mechanism will be used on the server side.
The DbDataReader object is much faster. Please try to use a DbDataReader instead of a DbDataAdapter. Use it to fill a generic List, then bind your DataGrid to that List.
However, it looks like something is wrong with your connection itself. How can you be sure the application is fetching data or trying to establish a connection ? To check this, change your query to a very fast one like "select sysdate from dual" to check whether the problem is coming from a connection attempt or not.

C# Sql Connection String

I'm a 17 year old software engineering student and am having trouble with linking my sql database to my C# Win App. I was able to accomplish this task using a access database but the database needs to be in SQL. Any Help would be greatly appreciated!
The code i have so far is :
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb; // all Non-SqlServer Databases ie oracle, access, sqlLite
using System.Configuration;
namespace SqlWinApp
{
public partial class Form1 : Form
{
// Declare and init data objects
// Connect to an external data source
//OleDbConnection cnDataCon =
// new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=H:/SEWD/ASP/dataTestJr/App_Data/dbWaxStax.accdb");
SqlConnection cnDataCon =
new SqlConnection(ConfigurationManager.ConnectionStrings["cnExternalData"].ConnectionString);
// dataset: Container object for data tables
DataSet dsData = new DataSet();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
cnDataCon.Open();
{
loadDdlTitles();
}
}
catch (Exception errDesc)
{
string strMsgError = "Error encountered on open: " + errDesc.Message.ToString().Replace('\'', ' ');
MessageBox.Show(#"<script language='javascript'>alert('" + strMsgError + "')</script>");
MessageBox.Show(#"<script language='javascript'>alert('Application will terminate')</script>");
return;
}
}
private void loadDdlTitles()
{
//Response.Write(#"<script language='javascript'>alert('loadDDlTitles')</script>");
// store sql into a string in order to be utilized at a later time.
string strSqlTitles = "SELECT * FROM tblTitles ORDER BY title";
// data adapters act as data filters
OleDbDataAdapter daTitles = new OleDbDataAdapter();
// command syncs the data source with the filter (data sdapter) and readies it for instantiation
OleDbCommand cmNameTitles = new OleDbCommand(strSqlTitles, cnDataCon);
// select command syncs the filter with the data
daTitles.SelectCommand = cmNameTitles;
try
{
daTitles.Fill(dsData, "tblTitlesInternal"); // blow pt.
}
catch (Exception errDesc)
{
string strMsgError = "Error encountered in data adapter object: " + errDesc.Message.ToString().Replace('\'', ' ');
MessageBox.Show(#"<script language='javascript'>alert('" + strMsgError + "')</script>");
MessageBox.Show(#"<script language='javascript'>alert('Application will terminate')</script>");
}
// Connect control obj to datasource and populate
ddlTitle.DataSource = dsData.Tables["tblTitlesInternal"];
ddlTitle.DisplayMember = "nameTitle";
ddlTitle.ValueMember = "nameTitlesID";
}
}
}
In my App.config i have:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="cnExternalData" connectionString="Data Source=|DataDirectory|215-6576.All-Purpose Handyman.dbo; Provider=Microsoft.ACE.OLEDB.12.0" />
<add name="SqlWinApp.Properties.Settings.ConnectionString" connectionString="Data Source=215-6576;User ID=sa"
providerName="System.Data.SqlClient" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
Finally, My database is named 215-6576.All-PurposeHandyman.dbo and the table i am using is named tblTitles. Any help again would be greatly appreciated! Thank you!
An invaluable website I've gone to repeatedly is ConnectionStrings.com.
Assuming everything you already have is correct, you just need to modify your SQL connection string in the config file:
<add name="SqlWinApp.Properties.Settings.ConnectionString" connectionString="Server=215-6576;User ID=sa; Database=All-PurposeHandyman; Password=password"
providerName="System.Data.SqlClient" />
If your sa account has a password, you will need to provide that as well via "Password=[Password]" in that same connectionString attribute.
EDIT
In your C# code, you don't need the braces around your call to loadDdlTitles();, you can safely remove those.
EDIT2
Added password attribute into modified connection string to make clear how it should work.
Well, I see 3 problems just off the bat (and there might be more if I looked more closely). The two that are causing you trouble are:
You're still calling your Access connection string
Your SQL connection string is formatted incorrectly.
The third problem isn't major, but it'll be annoying when you go to fix #1: your connection string name is really long.
Modify your sql connection string thusly:
<add name = "SqlConnection" connectionString="[yourConnectionStringHere]" />
Then modify your calling code:
SqlConnection cnDataCon =
new SqlConnection(ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString);
For the specific connection string, I recommend heading to http://connectionstrings.com and taking a look. But it will be something like this:
Server=myServerAddress;Database=myDataBase;User Id=myUsername; Password=myPassword;
You need to have the server/machine name in the connection string. This link has some information and examples to use:
http://msdn.microsoft.com/en-us/library/jj653752%28v=vs.110%29.aspx

Change Database during runtime in Entity Framework, without changing the Connection

I have a server that hosts 50 databases with identical schemas, and I want to start using Entity Framework in our next version.
I don't need a new connection for each of those databases. The privileges of the one connection can talk to all of the 50 databases, and for data management and speed (this is a WebAPI application) I don't want to instantiate a new EF context every time I talk to each of the databases if I don't have to, unless of course if this occurs each time a request comes to the server then no big deal.
All I really need is the ability to change the USE [databasename] command, which I assume eventually gets sent to the server from EF.
Is there a way to accomplish this in code? Does EF maintain a read/write property in the Context that refers to the database name that could be changed on the fly before calling SaveChanges(), etc.??
Thank you!!!
bob
Don't Work hard, work smart !!!!
MYContext localhostContext = new MYContext();
MYContext LiveContext = new MYContext();
//If your databases in different servers
LiveContext.Database.Connection.ConnectionString = LiveContext.Database.Connection.ConnectionString.Replace("localhost", "Live");
//If your databases have different Names
LiveContext.Database.Connection.ConnectionString = LiveContext.Database.Connection.ConnectionString.Replace("DBName-Localhost", "DBName-Live");
the structure for databases should be the same ;)
You can take a look at:
SO question about passing existing SQL Connection to
EntityFramework Context
and at this article describing how to
change database on existing connection.
Please let me know if any additional help is needed.
Edited
Updated 2nd link to point to SqlConnection.ChangeDatabase method.
So eventually code would look similarly to the following:
MetadataWorkspace workspace = new MetadataWorkspace(
new string[] { "res://*/" },
new Assembly[] { Assembly.GetExecutingAssembly() });
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
using (EntityConnection entityConnection = new EntityConnection(workspace, sqlConnection))
using (NorthwindEntities context = new NorthwindEntities(entityConnection))
{
// do whatever on default database
foreach (var product in context.Products)
{
Console.WriteLine(product.ProductName);
}
// switch database
sqlConnection.ChangeDatabase("Northwind");
Console.WriteLine("Database: {0}", connection.Database);
}
It is very simple
I had
public WMSEntities() : base("name=WMSEntities") //WMSEntities is conection string name in web.config also the name of EntityFramework
{
}
already in autogenerated Model.Context.cs of edmx folder.
To connect to multiple database in runtime, I created another constructor that takes connection string as parameter like below in same file Model.Context.cs
public WMSEntities(string connStringName)
: base("name=" + connStringName)
{
}
Now, I added other connection string in Web.Config for example
<add name="WMSEntities31" connectionString="data source=TESTDBSERVER_NAME;initial catalog=TESTDB;userid=TestUser;password=TestUserPW/>
<add name="WMSEntities" connectionString="data source=TESTDBSERVER_NAME12;initial catalog=TESTDB12;userid=TestUser12;password=TestUserPW12/>
Then, when connecting to database I call below method passing connectionString name as parameter
public static List<v_POVendor> GetPOVendorList(string connectionStringName)
{
using (WMSEntities db = new WMSEntities(connectionStringName))
{
vendorList = db.v_POVendor.ToList();
}
}
Here's my solution for just changing the database name. Simply pull the string from the web or app.config file, modify it, and then instantiate:
string yourConnection = ConfigurationManager.ConnectionStrings["MyEntities"].ConnectionString.Replace("MyDatabase", yourDatabaseName);
dcon = new MyEntities(yourConnection);
I have implemented this in my current project in which we have a common security database and different database for every client in the project. So our security database has a table that contain connection string for every other database. We just pass client id and get the connection string of the client database..
For this add two EDMX one for the common database and other for common schema databases. When user login or what might be your scenario to choose database go to common databse and get the connection string and create object of the needed database. Here is Code sample any, if any quer let me know..
You can keep connection string regarding every other database in a table in a a common database shared by all the other database.
EntityInstance_ReviewEntities.GetContext(GetConnectionString(ClientId));
private string GetConnectionString(int TenantId)
{
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
ISecurityRepository objSecurity = new SecurityRepository();
string tenantConnectionString = objSecurity.GetClientConnectionString(TenantId);
entityBuilder.ProviderConnectionString = tenantConnectionString;
entityBuilder.Provider = "System.Data.SqlClient";
entityBuilder.Metadata = #"res://*/ClientEntity.YourEntity.csdl|res://*/ClientEntity.ADBClientEntity.ssdl|res://*/ClientEntity.YourEntity.msl";
return entityBuilder.ToString();
}
EntityConnection.ChangeDatabase method is not supported, but SqlConnection.ChangeDatabase works fine.
So you have to use SqlConnection in entity framework database's constructor:
using MvcMyDefaultDatabase.Models;
using System.Data.Metadata.Edm;
using System.Data.SqlClient;
using System.Data.EntityClient;
using System.Configuration;
using System.Reflection;
public ActionResult List(string Schema)
{
SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
MetadataWorkspace workspace = new MetadataWorkspace(new string[] { "res://*/" }, new Assembly[] { Assembly.GetExecutingAssembly() });
EntityConnection entityConnection = new EntityConnection(workspace, sqlConnection);
sqlConnection.Open();
sqlConnection.ChangeDatabase(Schema);
Models.MyEntities db = new MyEntities(entityConnection);
List<MyTableRecords> MyTableRecordsList = db.MyTableRecords.ToList();
return View(MyTableRecordsList);
}
With this code you can read the tables with the same format (same table name and same fields) of several schema passing the database name in the "Schema" string.
For SQL Server, if you want to change only the database, not a connection, try:
public class XXXXDbContext : DbContext
{
public string databaseName
{
set
{
Database.GetDbConnection().Open();
Database.GetDbConnection().ChangeDatabase(value);
}
}
}

Database connection simplified - Is this right?

I'm trying to teach myself c#, and have found various examples on connecting to a MSSQL database. What I've done seems to be the simplest way to do it, but still seems overly complicated.
Is there a better way?
here's my code:
static void dbcon()
{
List<int> familyID = new List<int>();
String connString = "Server=[myServer]\\[myInstance];Database=[dbName];User Id=[userID};Password=[password];";
using (var sqlconn = new SqlConnection(connString))
{
using (var cmd = sqlconn.CreateCommand())
{
try
{
sqlconn.Open();
cmd.CommandText = "SELECT id FROM family";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
familyID.Add(Convert.ToInt32(reader["id"].ToString()));
}
}
foreach (int tempy in familyID)
{
Console.WriteLine("id: " + tempy);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
This is fine for an app that only runs one sql statement, but you wouldn't want to use all that code every time you wanted new data.
What you want to do is separate the code that creates the connection, from the code that gets and runs the sql, from the code that deals with the results.
This way, the connection code (and possibly the data display code) can be written once and called each time you want to execute different sql, and you only have to concentrate on how to write the code that gets the data you want.
hth
Details: First of all welcome to Stackoverflow. Just a few tips below
Having your connection string hard coded like that is bad practice. You should ALWAYS have it in your App.config (or Web.config if it is a web application). The reason is because if you have it hard coded and your boss ask you to change the Applications Database connection string you will need to recompile the entire application. If you have it in a App.config file you just need to change it (open it up with notepad) and save it.
Example on how to add it to the app.config
<configuration>
<connectionStrings>
<add name="myConnectionString"
connectionString="Data Source=localhost;Initial Catalog=MySQLServerDB;
Integrated Security=true" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
Then to access it in your code (You will need to add a reference to System.Configuration as well as add using System.Configuration;)
string connString = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
In regards to your other code I would change your exception catching to include the Sql Exception first and then fall back to any other exceptions.
catch (SqlException ex)
{
// Handle the Sql Exception code
}
catch (Exception ex)
{
// Handle the Normal Exception code
}
The example contained in the docs for SqlConnectionStringBuilder is quite easy to follow and understand as an alternative way.
System.Data.SqlClient.SqlConnectionStringBuilder builder =
new System.Data.SqlClient.SqlConnectionStringBuilder();
builder["Data Source"] = "(local)";
builder["integrated Security"] = true;
builder["Initial Catalog"] = "AdventureWorks;NewValue=Bad";
Console.WriteLine(builder.ConnectionString);
Edit:
Actually, the example I copied above shows you how the SqlConnectionStringBuilder class handles an "...invalid value in a safe manner". Whoops. At least it gives you an idea of how it works.
For more info on the various methods of obtaining, storing and constructing your connection string within ADO.NET, look at the MSDN documentation on Connection Strings

Categories