I am using Dapper.NET for my database connections.
So far, I have resorted to hand writing all the SQL I need for Inserts and Updates, I've found this old post from Sam Saffron
Performing Inserts and Updates with Dapper
However, it doesn't lead to anything conclusive with regards to how to do inserts and updates from POCO objects, other than a few links to code that are several years old by now.
Since then, has a new small helper library to autogenerate what is needed popped up?
You can use Dapper.Contrib
//Insert one entity
connection.Insert(new Car { Name = "Volvo" });
//Insert a list of entities
connection.Insert(cars);
//Update one entity
connection.Update(new Car() { Id = 1, Name = "Saab" });
//Update a list of entities
connection.Update(cars);
See more examples here.
Related
I am using EF for my web application and have encountered a strange error. I am trying to update a record in my DB, but even though the context.Database.ExecuteSqlCommand call returns 1, when I then call context.SaveChanges(), it returns 0 and the changes are not visible in the database.
Here is the code:
List<int> ids = new List<int> { 1, 2, 3 };
using (var context = new TestDbContext())
{
int rows=context.Database.ExecuteSqlCommand("UPDATE [Records] SET [ExampleFlag] = 1 WHERE Id in (#ids)",new SqlParameter("#ids",String.Join(",", ids)));
int rows2 = context.SaveChanges();
}
For some reason when debugging, rows equals 1, but rows 2 equals 0. As if it couldn't commit the changes to the database.
Any ideas on what may cause this?
These two ways to write to the database are almost two different worlds.
The core function of an Object-Relational Mapper (ORM) like Entity Framework is to keep an object model (for example in C#) and a relational database model in sync with one another. Therefore it is capable of tracking changes in the object model and writing these changes to the database.
Some ORM's, as a kind of courtesy, offer lower-level APIs to interact with the database. However, these functions don't interact with the ORM function, vise versa.
In other words, whatever statement is executed by DbContext.Database.ExecuteSqlCommand, EF's change tracker is completely oblivious of it. If no entity objects were modified by C# code, the change tracker has nothing to do. The executed SQL code has no effect on tracked entity objects.
Hello all you helpful folks!
I have been tasked with converting our RDBM into a Graph database for testing purposes. I am using Neo4J and have been successful on importing various tables into their appropriate nodes. However, I have run into a slight hiccup when it comes to the department node. Certain department are partnered with a particular department. Within the RDBMS model, this is simple a column named: Is_Partner because this database was originally set up with one partner in mind (Hence the whole: Moving to a Graph database thing).
What I need to do is match all department with the Is_Partner value of 1 and assign a relationship to from the partner who has the value of 1 in Is_Partner and assign it to a specific partner (Edge: ABBR, Value: HR). I have written the script, but it tells me it's successful, but 0 edits are made...
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///Department.csv" AS row
MATCH (partner:Department {DepartmentID: row.DepartmentID})
WHERE row.IS_PARTNER = "1"
MERGE (partner)-[:IS_PARTNER_OF]->(Department{ABBR: 'HR'});
I'm pretty new to Graph Databases, but I know Relational Databases quite well. Any help would be appreciated.
Thank you for your time,
Jim Perry
There are a few problems with your query. If you want to filter on CSV use WITH statement with a WHERE filter. Also you want to MERGE HR department node separately and then MERGE relationship separately.
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///Department.csv" AS row
WITH row WHERE row.IS_PARTNER = "1"
MATCH (partner:Department {DepartmentID: row.DepartmentID})
MERGE (dept:Department{ABBR: 'HR'}))
MERGE (partner)-[:IS_PARTNER_OF]->(dept);
If it still return no results/changes, check out if your MATCH statement return anything as this is usually the problem.
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///Department.csv" AS row
WITH row WHERE row.IS_PARTNER = "1"
MATCH (partner:Department {DepartmentID: row.DepartmentID})
RETURN partner
I am fairly new to visual basic and know only a little about LINQ and SQL. I know how to select items from an array with LINQ, but what I can't figure out how to do is access a database using an IQueryable. I connected the database to my project, added two classes from the database to the "LINQ to SQL" .dbml file and saved it. In my programming assignment, I am not supposed to create a data source (table thing) to display the data, but update my own interface manually. In order to do it, I was told to instantiate this:
Private dogs As System.Linq.IQueryable(Of Dog)
(Dog is a class that I added to my .dbml file from the database file)
Also, I am told it involves using a method
.AsEnumerable.ElementAt(index As Integer)
And somehow I am supposed to load database data from/using this. Help please if you can. I got screwed over by my professors as our online assignment program was down the whole thanksgiving break so I'm here doing this at the last minute. Thanks.
You have to make an instance of your data context class (which has the same name as your dbml + "DataContext"). Let's say it is AnimalsDataContext:
using (var context = new AnimalsDataContext())
{
var dogs = context.Dogs;
....
}
We have a Silverlight application that uses WCF Data Services. We want to add logging functionality: when a new row is generated, the primary key for this new row is also recorded in the logging table. The row generation and the logging should occur within the same transaction. The primary keys are generated via the database (using the IDENTITY keyword).
This might best be illustrated with an example. Here, I create a new Customer row, and in the same transaction I write the Customer's primary key to an AuditLog row. This example uses a thick client and the Entity Framework:
using (var ts = new TransactionScope())
{
AuditTestEntities entities = new AuditTestEntities();
Customer c = new Customer();
c.CustomerName = "Acme Pty Ltd";
entities.AddToCustomer(c);
Debug.Assert(c.CustomerID == 0);
entities.SaveChanges();
// The EntityFramework automatically updated the customer object
// with the newly generated key
Debug.Assert(c.CustomerID != 0);
AuditLog al = new AuditLog();
al.EntryDateTime = DateTime.Now;
al.Description = string.Format("Created customer with customer id {0}", c.CustomerID);
entities.AddToAuditLog(al);
entities.SaveChanges();
ts.Complete();
}
It's a trivial problem when developing a thick client using Entity Framework.
However, using Silverlight and ADO.NET data services:
SaveChanges can only be invoked
asynchronously
I'm not sure TransactionScope is available
I'm not sure if generated keys can be reflected in the client Edit: According to Alex James they are indeed reflected in the client
So, will this even be possible?
Short Answer: No this is not even possible
Okay... so:
Generated Keys are reflected in the client.
You can transact one SaveChanges operation by using DataServiceContext.SaveChanges(SaveChangesOption.Batch)
But unfortunately you can't do anything to tie one request to the response of another, and wrap them both in one transaction.
However...
If you change the model by making a CustomerAuditLog method that derives from AuditLog:
// Create and insert customer ...
// Create audit log and relate to un-insert customer
CustomerAuditLog al = new CustomerAuditLog();
al.EntryDateTime = DateTime.Now;
al.Description = string.Format("Created customer with {Customer.ID}");
// assuming your entities implement INotifyPropertyChanging and you are using
// the Data Services Update to .NET 3.5 SP1 to use DataServiceCollection
// to notify the DataServiceContext that a relationship has been formed.
//
// If not you will manually need to tell Astoria about the relationship too.
al.Customer = c;
entities.AddToAuditLog(al);
entities.SaveChanges();
And having some sort of logic deep in your underlying DataSource or maybe even the database to replace {Customer.ID} with the appropriate value.
You might be able to get it to work, because if two inserts happen in the same transaction and one (CustomerAuditLog) depends on another (Customer) they should be ordered appropriately by the underlying data source.
But as you can see this approach is kind of hacky, you don't want a Type for each possible audit message do you! And ... it might not even work.
Hope this helps
Alex
Data Services Team, Microsoft
I'm in the process of learning LINQ to Entities and WPF so forgive me if I get some terminology wrong. I have a model which contains Clients and I want the user to be able to bulk enter up to 20 clients at a time (this will be done by data entry staff off a paper list so I want to avoid entering one and saving one).
I was planning on adding 20 new clients to my model and have a datagrid/listbox bound to this.
In LINQ, how do I select out the newly added records to the model? I could rely on certain fields being blank but is there a better method? Alternatively, is there another way of doing this?
DataContext db; // ...
db.GetChangeSet();
The change set will contain lists of newly insert, update and delete operations. If you access that prior to any SubmitChanges you should be able to get what you want. However LINQ does preform inserts in a transactional manner so what is it that you wanna achieve here?