Can't insert in a table having composite primary key using LINQ - c#-4.0

Added that SqlConnection part as someone suggests on this website but still getting exception
Cannot insert explicit value for identity column when identity insert is OFF
on dv.SubmitChanges();
The composite primary key is composed of stid and bookid.
Also please tell me how I can make this query without concatenating textbox's value i.e bname.Text
using (SqlConnection conn = new SqlConnection(cs))
{
conn.Open();
using (DataClasses1DataContext dv = new DataClasses1DataContext())
{
var iq = (from b in dv.Books
where SqlMethods.Like(b.name, "%" + bname.Text + "%")
select b.Id).FirstOrDefault();
IssueInfo info = new IssueInfo()
{
stid = Convert.ToInt32(rollno.Text),
due_date = Convert.ToDateTime(dateTimePicker1.Text),
bookid = Convert.ToInt32(iq)
};
dv.ExecuteCommand("SET IDENTITY_INSERT IssueInfo ON");
dv.IssueInfos.InsertOnSubmit(info);
dv.SubmitChanges();
dv.ExecuteCommand("SET IDENTITY_INSERT IssueInfo OFF");
}
}

Related

Cannot insert into Cassandra table, getting SyntaxError

I have an assignment where I have to build a Cassandra database. I have connected Cassandra with IntelliJ, i'm writing in java and the output is shown in the command line.
My keyspace farm_db contains a couple of tables in wish i'm would like to insert data. I would like to insert the data with two columns and a list all in one row, in the table 'farmers'. This is a part of my database so far:
cqlsh:farm_db> use farm_db;
cqlsh:farm_db> Describe tables;
farmers foods_dairy_eggs foods_meat
foods_bread_cookies foods_fruit_vegetables
cqlsh:farm_db> select * from farmers;
farmer_id | delivery | the_farmer
-----------+----------+------------
This is what i'm trying to do:
[Picture of what i'm trying to do][1]
I need to insert the collection types 'list' and 'map' in 'farmers' but after a couple of failed attempts with that I tried using hashmap and arraylist instead. I think this could work but i seem to have an error in my syntax and I have no idea what the problem seem to be:
Exception in thread "main" com.datastax.driver.core.exceptions.SyntaxError: line 1:31 mismatched input 'int' expecting ')' (INSERT INTO farmers (farmer_id [int]...)
Am I missing something or am I doing something wrong?
This is my code:
public class FarmersClass {
public static String serverIP = "127.0.0.1";
public static String keyspace = "";
//Create db
public void crateDatabase(String databaseName) {
Cluster cluster = Cluster.builder()
.addContactPoints(serverIP)
.build();
keyspace = databaseName;
Session session = cluster.connect();
String create_db_query = "CREATE KEYSPACE farm_db WITH replication "
+ "= {'class':'SimpleStrategy', 'replication_factor':1};";
session.execute(create_db_query);
}
//Create table
public void createFarmersTable() {
Cluster cluster = Cluster.builder()
.addContactPoints(serverIP)
.build();
Session session = cluster.connect("farm_db");
String create_farm_table_query = "CREATE TABLE farmers(farmer_id int PRIMARY KEY, the_farmer Map <text, text>, delivery list<text>); ";
session.execute(create_farm_table_query);
}
//Insert data in table 'farmer'.
public void insertFarmers(int id, HashMap< String, String> the_farmer, ArrayList <String> delivery) {
Cluster cluster = Cluster.builder()
.addContactPoints(serverIP)
.build();
Session session = cluster.connect("farm_db");
String insert_query = "INSERT INTO farmers (farmer_id int PRIMARY KEY, the_farmer, delivery) values (" + id + "," + the_farmer + "," + delivery + ");";
System.out.println(insert_query);
session.execute(insert_query);
}
}
public static void main(String[] args) {
FarmersClass farmersClass = new FarmersClass();
// FarmersClass.crateDatabase("farm_db");
// FarmersClass.createFarmersTable();
//Collection type map
HashMap<String, String> the_farmer = new HashMap<>();
the_farmer.put("Name", "Ana Petersen ");
the_farmer.put("Farmhouse", "The great farmhouse");
the_farmer.put("Foods", "Fruits & Vegetables");
//Collection type list
ArrayList<String> delivery = new ArrayList<String>();
String delivery_1 = "Village 1";
String delivery_2 = "Village 2";
delivery.add(delivery_1);
delivery.add(delivery_2);
FarmersClass.insertFarmers(1, the_farmer, delivery);
}
The problem is the syntax of your CQL INSERT query:
String insert_query = \
"INSERT INTO farmers (farmer_id int PRIMARY KEY, the_farmer, delivery) \
values (" + id + "," + the_farmer + "," + delivery + ");";
You've incorrectly added int PRIMARY KEY in the list of columns.
The correct format is:
INSERT INTO table_name (pk, col2, col3) VALUES ( ... )
For details and examples, see CQL INSERT. Cheers!

Save serial number in Excel using WPF (OLEDB)

My application in WPF allows user to save some data from text boxes into Excel file (using OLEDB connection). I wish to add feature that every time new row is saved into Excel file a sequence number is added into EventID column in that Excel file.
But I'm getting an error while running the application related to parameter #EventId saying: 'parameter has no default value'.
I expect I have written wrong sql1 command to generate the serial number.
I'd appreciate your help.
private void btnSaveNewEvent1_Click_1(object sender, RoutedEventArgs e)
{
object eventName = txtEventName.Text;
object typeValue = txtEventType.Text;
object nameValue = txtAttributeName.Text;
object attribvValue = txtAValue.Text;
object descValue = txtEventDescrip.Text;
System.Data.OleDb.OleDbConnection MyConnection;
System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand();
System.Data.OleDb.OleDbCommand myCommand1 = new System.Data.OleDb.OleDbCommand();
String sql = null;
String sql1 = null;
MyConnection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source='excel_file\\events2.xlsx'; " +
"Extended Properties=\"Excel 12.0 Xml;HDR=YES;\"");
try
{
//SQL STATEMENT TO SAVE INSERTED BY THE USER VALUES FROM THE TEXT BOXES
//SQL1 STATEMENT TO GENERATE EVENTID NUMBER EACH TIME THE USER SAVES NEW ROW OF DATA
MyConnection.Open();
myCommand.Connection = MyConnection;
sql = "Insert into [events$] (EventID,EventName, Type, Name, [Value], Description) values(#EventID,#EventName,#Type,#Name,#Val,#Desc)";
myCommand.CommandText = sql;
myCommand.Parameters.AddWithValue("#EventID",sql1);
myCommand.Parameters.AddWithValue("#EventName", eventName ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Type", typeValue ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Name", nameValue ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Val", attribvValue ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Desc", descValue ?? DBNull.Value);
myCommand1.Connection = MyConnection;
sql1= "DECLARE #i int = 0 while #i < EventID BEGIN SET #i = EventID + 1 END";
myCommand1.CommandText = sql1;
myCommand.ExecuteNonQuery();
myCommand1.ExecuteNonQuery();
MyConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
MyConnection.Close();
Events eventsWindow = new Events();
eventsWindow.dgData.Items.Refresh();
}
}
Since your command is running before command1 sql1 = null, That is what your problem is.
You need to set the value of sql1 before executing the command. If you really want the value to be null you need to use DBNull.Value as you have for the other parameters.

Azure Table Storage: How can I create a dynamic where clause?

Ok, so I am using Azure Table Storage for the first time in a ASP.NET MVC 3 application.
I have a table entity that has a user ID as its RowKey. I have a list of user IDs and need to get all of the entities that have one of the User IDs.
In traditional SQL it would be a simple OR statement in the where clause that you can dynamically add to:
select * from blah
where userID = '123' or userID = '456' or userID = '789'
but I haven't found the equivalent in the Azure SDK.
Is this possible with Azure Table Storage?
Thanks,
David
The .Net client for Azure Table Storage has features to generate and combined filters.
So that you can write your filter expression like that
string[] split = IDs.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
string mainFilter = null;
foreach (var id in split)
{
var filter = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, id);
mainFilter = mainFilter != null ? TableQuery.CombineFilters(mainFilter, TableOperators.And, filter) : filter;
}
var rangeQuery = new TableQuery<Blah>().Where(mainFilter);
var result = table.ExecuteQuery(rangeQuery);
I am using Windows Azure Storage 7.0.0 and you can use Linq query to filter.
Unfortunately Contains method is not supported by the Table Service but you can write a simple method to build dynamically your linq query:
public static class ContainsExtension
{
public static Expression<Func<TEntity, bool>> Contains<TEntity,
TProperty>(this IEnumerable<object> values,
Expression<Func<TEntity, TProperty>> expression)
{
// Get the property name
var propertyName = ((PropertyInfo)((MemberExpression)expression.Body).Member).Name;
// Create the parameter expression
var parameterExpression = Expression.Parameter(typeof (TEntity), "e");
// Init the body
Expression mainBody = Expression.Constant(false);
foreach (var value in values)
{
// Create the equality expression
var equalityExpression = Expression.Equal(
Expression.PropertyOrField(parameterExpression, propertyName),
Expression.Constant(value));
// Add to the main body
mainBody = Expression.OrElse(mainBody, equalityExpression);
}
return Expression.Lambda<Func<TEntity, bool>>(mainBody, parameterExpression);
}
}
So that you can build dynamic queries easily :
var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["TableStorageConnectionString"]);
var tableClient = storageAccount.CreateCloudTableClient();
var table = tableClient.GetTableReference("Blah");
var split = IDs.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
// Create a query: in this example I use the DynamicTableEntity class
var query = table.CreateQuery<DynamicTableEntity>()
.Where(split.Contains((DynamicTableEntity d) => d.RowKey));
// Execute the query
var result = query.ToList();
Alrighty, with a bit more digging I found the answer.
You can construct a where filter using the syntax found here: http://msdn.microsoft.com/en-us/library/windowsazure/ff683669.aspx
So for my little example it ended up looking like this:
I have a comma delimited string of IDs sent to this method
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["TableStorageConnectionString"]);
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("Blah");
string[] split = IDs.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
string filter = null;
for (int i = 0; i < split.Length; i++)
{
filter += " RowKey eq '" + split[i] + "' ";
if (i < split.Length - 1)
filter += " or ";
}
TableQuery<Blah> rangeQuery = new TableQuery<Blah>().Where(filter);
var result = table.ExecuteQuery(rangeQuery);
Result has the list of goodies I need.
One thing to keep in mind is that you wouldn't want to use this on a really large table because I am only getting the RowKey which causes a table scan. If you use the PartitionKey and RowKey together it is more efficient. My table is pretty small (few hundred records at most) so it shouldn't be an issue.
Hope this helps someone.
David

EntityDataReader to ToList()

my code :
public List<Book> GetBook(string Field, object Value)
{
using (EntityConnection conn = new EntityConnection("name=Entities"))
{
conn.Open();
// Create an EntityCommand.
using (EntityCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "Select VALUE b FROM Entities.Book as b where Cast(b." + Field + " as Edm.String) like '%" + Value.ToString() + "%'";
// Execute the command.
using (EntityDataReader rdr =
cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
conn.Close();
var s = from d in rdr.OfType<Book>().AsEnumerable()
select d;
return (s.ToList());
}
}
}
return (null);
}
why The result is always empty???
What is the correct code?
Why are you closing connection before you started to read from the reader? Reader is like cursor - it doesn't buffer all results to memory when you open it but it loads them incrementally so you could easily terminate connection (and reading functionality as well) before you read any result. You don't have to close the connection explicitly - that is responsibility of using block.
You can also use SQL profiler to validate the it really builds the query you expect.
using (EntityConnection conn = new EntityConnection("name=Entities"))
{
conn.Open();
// Create an EntityCommand.
using (EntityCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "Select VALUE b FROM Entities.Book as b where Cast(b." + Field + " as Edm.String) like '%" + Value.ToString() + "%'";
// Execute the command.
using (EntityDataReader rdr =
cmd.ExecuteReader(CommandBehavior.SequentialAccess))
{
var s = from d in rdr.OfType<Book>().AsEnumerable()
select d;
return (s.ToList());
}
}
}
s.ToList().Count returns 0 because rdr.OfType<Book> is always empty collection. EntitDataReader doesn't materialize entities - it is just wrapper about database related DataReader and it works in the same way. You must read columns and fill them to properties of your entity.
If you don't want to do it you can use objectContext.Translate method but once you start to work with ObjectContext you don't need EntityCommand and EntityDataReader at all.

Searching with ID NO subsonic

public List<EmployeeDirectory> employee = new Health_Scheme_SystemDB.Select
.From<EmployeeDirectory>()
.Where(EmployeeDirectoryTable.ID_NOColumn).Contains(1005)
.ExecuteTypedList<EmployeeDirectory>();
The .Select is giving me problems. Its saying that 'Health_Scheme_System.Health_Scheme_SystemDB.Select' is a 'property' but is used like a 'type'
Remove the new - you are not creating a new instance so you shouldn't use new.
public List<EmployeesX> GetID(string IDNO)
{
Health_Scheme_System.Health_Scheme_SystemDB db = new Health_Scheme_System.Health_Scheme_SystemDB();
var d = (from c in db.EmployeeDirectories
where c.ID_NO.Contains(IDNO)
select new EmployeesX { ID_NO = c.ID_NO, FIRST_NAME = c.FIRST_NAME, LAST_NAME = c.LAST_NAME, EMPLOYMENT_DATE = ((DateTime)c.EMPLOYMENT_DATE).Date, TERMINATION_DATE = ((DateTime)c.TERMINATION_DATE).Date, LOCATION_CODE = c.LOCATION_CODE });
return d.ToList<EmployeesX>();
}
Then bind the grid view with this code. obviously there the data input in the textbox only will be displayed in the gridview.
gvView.DataSource = da.GetID(txtIDNO.Text);
gvView.DataBind();

Resources