Deleting in Db4o Database Using Linq - c#

I have a problem with deleting from my Db4o database. At the moment i can store new objects and get them shown in a datagrid view. But for some reason i cannot delete the objects again. Here is the Linq i am using.
public void DeleteStudent(int ssn)
{
var config = Db4oFactory.NewConfiguration();
using (var db = Db4oFactory.OpenFile(config, "StudentDB"))
{
var query = (from StudentDB x in db
where x.SSN == ssn
select x);
if (query != null)
{
db.Delete(query);
}
}
}
I am getting the object that i want to delete by the ssn. I have tried debug and check that its not null and its not. I am getting the right object.
Here is the GUI part i am using.
private void btnDeleteStudent_Click(object sender, EventArgs e)
{
int ssn = Convert.ToInt32(txtSSN.Text);
studentDB.DeleteStudent(ssn);
gridStudents.DataSource = studentDB.GetAllStudents();
ClearBoxes(this);
}
i am getting the ssn from a textbox and giving it as a parameter when i click the delete button. And after that i am refreshing the gridview.
Hope one of you can help! i am new to Db4o so dont know a lot about it.

You are passing the wrong object to the db.
change your code to something like:
using (var db = Db4oFactory.OpenFile(config, "StudentDB"))
{
var query = (from StudentDB x in db
where x.SSN == ssn
select x).SingleOrDefault();
if (query != null)
{
db.Delete(query);
}
db.Commit();
}

Related

Clear Search Result in EntityFrameWork

I have a database called Employee and I am using entity framework version 6.1.3.
In my wpf application, I have button called Search, one textbox( searchField) for search field and a datagrid ( employeedatagrid)
When i enter input in search field, it gives expected output in datagrid view but after that when i enter again different input in searchfield, it just prints the new data just below the previous data. What I want is; When i enter different search field , then If there is already data in datagrid, I want to remove those old data from datagrid and prints only the new data.
Below is my C# Code
private void Search_Click(object sender, RoutedEventArgs e)
{
this.employeeDataGrid.ItemsSource = null;
this.employeeDataGrid.Items.Clear();
var text = SearchField.Text;
var query = employeeModel.Employees.Where(x => x.Country == text).Select(y => y);
foreach (var item in query)
{
employeeDataGrid.ItemsSource = employeeModel.Employees.Local;
}
}
Can anyone point out, what I am missing here ?
thanks.

How to get the key(id) of the binded checkListBox

I am have a Windows Forms application and also using SQL to get the data from my db. I have a binded checkListBox in my Windows Forms application and I would like to get the primary key (the value) of all the checked Items in my checkListBox. What I realize is in combo box, they have a build in method 'selectedValue' I am wondering if we can do the same thing in checkListBox by looping through the checkedItems in checkListBox and get its value
Let say in my db table, I have:
EmployeeId Employee Name
1 Jimmy
2 Pam
3 Bob
4 Kobe
My binded checkListBox showed something like
[x]Jimmy
[x]Pam
[]Bob
[]Kobe
Can I get the checkedItem item's id by using sql query. Now let say Jimmy and Pam is checked and I want to get their employeeId. I am not sure how to do it. Help will be appreciated.
select * from employee_table where employeeId = '"+checkListBox.SelectedValue+"'
or
foreach(var item = item.CheckedItems{
select * from employee_table where employeeId = '"items"';
}
You don't need to go to database again to retrieve Id of your items.
You can create a class for items that contains an Id and a Name property and override ToString method to return the string that you want to show in CheckedListBox:
public class ItemModel
{
public int Id { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
Then when loading data, you can select the output and shape it to ItemModel and then add these ItemModels to CheckedListBox:
private void Form_Load(object sender, EventArgs e)
{
var db = new TestDBEntities();
//Select items that you need and shape it to ItemModel
var list = db.Categories.Select(x => new ItemModel
{
Id = x.Id,
Name = x.Name
})
.ToList();
//We cast the list to object[] because AddRange method accept object[]
this.checkedListBox1.Items.AddRange(list.Cast<object>().ToArray());
}
Then when you need to know Id of checked items, you can simply cast each checked item to ItemModel an use its Id property:
private void button1_Click(object sender, EventArgs e)
{
this.checkedListBox1.CheckedItems.Cast<ItemModel>()
.ToList()
.ForEach(item =>
{
MessageBox.Show(string.Format("Id:{0}, Name:{1}", item.Id, item.Name));
});
}
Note:
If you use another method to connect to database, you can simply change this code to satisfy your requirements, for example this code uses ADO.Net objects to shape data to ItemModel:
private void CheckedListBoxSample_Load(object sender, EventArgs e)
{
var connection = #"data source=(localdb)\v11.0;initial catalog=TestDB;integrated security=True;MultipleActiveResultSets=True;";
var command = "SELECT Id, Name From Categories";
var dataAdapter = new System.Data.SqlClient.SqlDataAdapter(command, connection);
var table = new DataTable();
dataAdapter.Fill(table);
var list = table.Rows.Cast<DataRow>()
.Select(row => new ItemModel
{
Id = row.Field<int>("Id"),
Name = row.Field<string>("Name")
})
.ToList();
this.checkedListBox1.Items.AddRange(list.Cast<object>().ToArray());
}
Something along these lines might help you.
Basically what it does, is that it builds a parameterized query, and then adds all the selected items using SqlParameters. Then using the reader, you are able to parse each returned record. The code below will probably need some modifications for you to use it, but should help you getting started.
Although I would strongly suggest using an ORM like Entity Framework. Using an ORM you don't have to build your own queries, and allows you to use strong typed classes to "talk" to your database.
var query = "SELECT * FROM employee_table WHERE imployeeId IN (#ids)";
var ids = String.Join(","
MyCheckBoxList.Items
.Cast<ListItem>()
.Where(x => x.Selected)
.Select(x => x.Value);
using (var connection = new SqlConnection(myConnectionString))
{
connection.Open();
using(var command = new SqlCommand(query, connection)
{
command.Parameters.Add("ids", ids);
var reader = command.ExecuteReader();
while(reader.Read())
{
//get all the needed data from the reader
}
}
}

TableAdapter Query with optional WHERE paramerter

I am trying to create a TableAdapter query with an optional WHERE parameter.
This is my query:
SELECT Productos.Categoria, Productos.Subcategoria, Productos.Nombre,
Productos.Marca, Productos.Descripcion, Proveedores.Nombre AS Proveedor, Precios.Precio
FROM Precios, Productos, Proveedores
WHERE Precios.Producto_ID = Productos.ID AND Precios.Proveedor_ID =
Proveedores.ID AND Proveedores.Nombre = ?
I would like "Proveedores.Nombre = ?" to be optional or if ? = null or nothing, the query does not filter by Proveedores.Nombre
I have tried this:
(Proveedores.Nombre =#PNombre OR #PNombre = NULL)
But I have got an error:
Generated SELECT statement:
Error in WHERE clause near '#'.
Unable to parse the query text
Thank you very much for you help,
Regards
Andres
EDIT:
I ma in a windows form project. I am using a DataSource - DataSet linked to my access database. So to create FillBy() and GetData() I use a table-adapter which was automatically created when I inserted the DataSource to my WindowsForm.
This is the method created liked to the GetData() I am using:
public virtual DB_ProvProd2DataSet.ProductosDataTable GetDataByTodo(string Nombre) {
this.Adapter.SelectCommand = this.CommandCollection[5];
if ((Nombre == null)) {
throw new global::System.ArgumentNullException("Nombre");
}
else {
this.Adapter.SelectCommand.Parameters[0].Value = ((string)(Nombre));
}
DB_ProvProd2DataSet.ProductosDataTable dataTable = new DB_ProvProd2DataSet.ProductosDataTable();
this.Adapter.Fill(dataTable);
return dataTable;
}
Where this.CommandCollection[5] = the query and this.Adapter.SelectCommand.Parameters[0] is the input related to the '?' of the query.
I hope this helps!
Thanks!!!
Try assing it to a local variable:
string tmp= #PNombre
(Proveedores.Nomber==tmp || tmp == null)

Duplicate record issue when using Entity Framework and concurrent connections

var DoesNotExist = this.db.Regions.Where(!m.Reports.Any(r => r.ReportId == m.ReportId)).ToList();
foreach (var item in DoesNotExist)
{
Report rpt = new Report { ReportId = item.ReportId, ReportDate = endDate };
this.db.Reports.AddObject(rpt);
foreach (var Point in this.db.RegionalData.Where(s => s.ReportId == item.ReportId && s.ReportDate == lastendDate))
{
if (this.db.RegionalData.Where(d => d.ReportId == Point.ReportId).Count() == 0)
{
StateData sd = new StateData
{
ReportDate = endDate,
ReportId = Point.ReportId,
Female = Point.Female,
Male = Point.Male,
Total = Point.Total,
};
this.db.RegionalData.AddObject(sd);
}
}
}
if (DoesNotExist.Count() != 0)
{
this.db.SaveChanges();
}
I have the above code that checks if reports for a Region do not exist, and if they do not exist i insert them.
The problem i'm having is that if two users trigger the execution of this code a few seconds apart, two reports for the same region are created which creates duplicates since a region can only have one report.
How best can i resolve this?
I tried calling putting
if (missingReportData.Count() != 0)
{
this.db.SaveChanges();
}
immediately after this.db.Reports.AddObject(rpt); but still the issue persisted.
I would solve this by adding a unique index that prevents you from inserting two reports for the same region. Without seeing your model it's hard to say if it should be the primary key or not.
This way database server will throw an exception if there is already a report for that region. Then you can handle that exception by switching to an update or show an error to the user.
You can also use a transaction but you need to update EF4 to EF6.

My method is always returning false, why?

public bool IsUser(string username)
{
bool user = false;
using (var client = new datingEntities())
{
var result = from x in client.Person
select x;
foreach (var item in result)
{
if (item.Username == username)
{
user = true;
}
}
}
return user;
}
This method am I using to get data from a SQL database that I have. It's no problem with the database connection, it's just that it always is returning false even if the parameter username is existing in the database (double checked the data in the database). I tried this method before and then it worked but it don't. I'm using entity framework against my database
This will do:
public bool IsUser(string username)
{
using (var entities = new datingEntities())
{
return entities.Person.Any(p => p.Username == username);
}
}
Now you request all user entities and loop through them to see if the user matches the queried username. You should let Entity Framework or LINQ write the queries, which you do as demonstrated above.
As for the reason your function is not working: set a breakpoint, find out if any users are found at all. We can't debug that for you.
use "ToUpper()"
if (item.Username.ToString().ToUpper() == username.ToUpper())
{
user = true;
}
[EDITED]
OR use "Equal"
item.Equals(username, StringComparison.OrdinalIgnoreCase)
I would convert both item.UserName and username values to the lowercase and compare them this way. This looks more reliable. Also, your linq query can be changed to avoid the loop as follows:
var result = from x in client.Person
where x.UserName.ToLower() == userName.ToLower()
select x;
My answer is less good than others as mentioned in the comments, but I left it here for reference purposes.
I'm not sure why it returns false but what you are trying to achieve is usually done in the following way:
public bool IsUser(string username)
{
using (var client = new datingEntities())
{
User user = client.Persons.SingleOrDefault(u => u.Username == username);
return user != null;
}
}
This way is a lot more efficient than your way because you first pull all User records from the database to then iterate through them to find the one user with the Username equal to the provided string. My way tries to get the one record with the Username equal to the provided string, if no such record exists I return false and otherwise true.

Categories