I am using Entity Framework to save some data in a SQLite database file.
This is my table in DB file
ID Name Username Pwd
ID is autoincrement, and rest of columns are of Text type
This is how I am saving my data into the database:
UserInfo userInfo=new UserInfo();
userInfo.Name="abc";
userInfo.Username="xyz";
userInfo.Pwd="123456";
using (var context = new ApplicationContext())
{
context.UserInfo.Add(userInfo);
context.SaveChanges();
}
The problem is, this code is not inserting any new row into the table. I also tried this before saving, but no luck
context.Entry<UserInfo>(userInfo).State = EntityState.Added;
context.ChangeTracker.DetectChanges();
I tried debugging and no exception is occurring.
How can I insert new row into a table using Entity Framework?
Possibilities that may cause an issue.
Right Click on your Entity Data Model and Update Model From Database. To make sure you have updated till the last change.
Make sure you are looking at the correct Database and Table. Every one makes this mistake once in a while.
Make sure you are using the valid connection string. Pointing the proper databases. Make sure its not a old db / some other backup db.
Make sure you are using the proper entity which is up to date.
The above code you have, its perfectly working fine to me. I just did a workout to sort out this issue.
The above points are guesses.
Refer this Link Entity Data Model Example & One More Example Code available here
I had a similar problem once and it can be a pain to determine what exactly causes this. One issue that might be causing such a behavior in EF is having multiple instances of the Context object such that when you call SaveChanges on your Context, you are actually calling it on a different instance than the one you added the entity on (and EF does not detect any changes in the entities or the new entity is not attached to the right context, causing SaveChanges to not send any SQL requests to the database).
I suggest debugging this in VS (using the object id feature) in order to see if you have multiple context instances. Using the Unit Of Work pattern together with repositories is a way to have a better control over the lifetime of the context objects in your application
Related
Writing an API and using EF Code First. It was working perfectly fine, then I moved the POCO Objects that I use to create the tables into a folder called POCO. Deleted the database as the ID's that I was using were all out for some reason, and no when I go to update the database using migrations I get the Invalid Object "dbo.sales" error and I can seem to find out what to do about this.
Can Anyone help?
You deleted your database and need to create a new database. You can't update it using database migrations, as there is no database to update.
Create a new database, and enable migrations.
Code First to a New Database
edit
In response to OPs comment.
To create a database using code first.
This tute is great.
Getting Started with Entity Framework 6 Code First using MVC 5
It's hard for me to give you specific advice, as I'm not sure what you've done to your project.
The project I'm working on uses Entity Framework 6.0 Code-First.
One of my co-workers, due to his lack of experience with EF, manually changed the field type of a field on the database to being decimal(28,10), instead of doing it the correct way in the OnModelCreating method of DbContext. Entity Framework allowed him to do so, never throwing an error upon any future migrations.
Last week, another co-worker was running into a problem with a process that clones records from that table, where the decimal values in the new records were being truncated to 2 decimal places (with no rounding occurring).
The code for that cloning resembles the following (using the Repository pattern on top of EF):
public void CloneAccounts(List<Account> accounts, int newQuarterID)
{
var newAccounts = new List<Account>();
accounts.ForEach(account =>
{
var clonedAccount = new Account
{
QuarterID = newQuarterID
AccountName = account.AccountName,
AccountNumber = account.AccountNumber,
Amount = account.Amount
};
newAccounts.Add(clonedAccount);
});
AccountRepository.AddMany(newAccounts);
AccountRepository.Save();
}
When I pointed out, as a side-point, that the declaration of the Amount field being decimal(28,10) should really be in OnModelCreating, he went ahead and did that, and added a migration. Doing that, interestingly enough, ended up solving the issue with the code above.
My question is two-fold:
Why did that issue not affect the creation of the original records as well, and only upon cloning?
Why did adding that line in OnModelCreating fix it?
Thanks!
If you didn't originally have any precision set, the default convention for code-first is to create decimal columns with precision of 18 and scale of 2 (so only two decimal places). I think it's possible the records had originally been truncated in the first place.
Also, by default, the SQL Server provider's SQL generator sets SqlParameter.Scale property to the scale defined in the model, unless you had TruncateDecimalsToScale set to false, which would affect database updates and inserts. I'm not sure how those records with additional decimal places ended up in the database, though.
When using codeFirst with EF it creates the model in code (C# or VB), then it replicates the model to your DB.
To answer your questions I could say that:
The issue did't affect at first because when you created your model all the changes were made directly to your DB, then you had your tables exactly the same as in the model.
Remember that Entity Framework is an ORM (Object Relational Mapper) it creates, for you and with little effort, a set of entities (classes) based on a domain model -- this domain model can exists it three different flavours: code-first, model-first, and database-first.
Code-first means that you start your project by creating a set of classes (aKa Entities) which will represent your relational model in your data base. (your source will be your classes and the target your database).
Model-first means that you start your project by using a visual tool, basically drag and drop, connecting points and so on, which lets you create a model which will represent your relational model in your data base. (your source will be your model and the target your database).
Database-first means that you start your project by selecting the model from a data source (usually a database), this approach will create for you a set of classes (Entities) in your visual studio project. (your source will be your database and the target your code).
So, whatever change you make in any of the above scenarios must be replicated from source to target via Entity Framework.
What happened here was a mistake from your co-worker, who made a change directly in your database, but it must had been done from your EF project (code first).
When you invoked ClonneAccounts EF made all the magic (connect to DB, execute a query, gets data, cast it to your entity classes, and then retrieve them or visceversa) --> this is when your app crashed because of an InvalidCastException.
EF does not check consistency, scheme or structure of your tables every time you invoke ClonneAccounts, it just retrieves data between Entities and Database and insert/update data. If you want to update/check consistency and replicate changes you have to do it manually. That is why until you fixed your model in the "code side" and ran the tool it replicated all changes to your db.
Hope it helps
Linked to this question:
Cannot Split Table with EF 5 - Code First - with existing database
But i think the answer to that question is actually not a problem with code first but with something i did whilst developing.
The scenario is this:
Had an existing database and used this to begin creating my data context
Began working with it but soon realised that naming conventions were poor and some tables needed remodelling.
Decided to create a new database with better conventions for existing tables taken across and remodelled the new bits
Updated the context to look at new Database
Even though migrations where not enabled, i was getting errors with the database being out of sync (even though up until this morning it was still pulling data)
I enabled migrations (comment in other question) and output to script. And you can see the sync changes are things like table names and Id properties etc.
I can't move forwards, the context seems does not like it when you switch databases on it like this (which i get to a point but this is really brittle). What i need to do somehow reset the context so it doesn't actually think any changes have been made to the database and it thinks it is working with an initial database again.
I have deleted the migrations folder, but that does nothing. Is there a any sort of way i can get this to happen?
Try deleting the __MigrationHistory table in the database. It's a system one.
Assume i have a big entity and want to create a typical CRUD application. A user shouldn't have the ability to save some fields of my entity.
So i see two ways to implement change-save logic:
a)
Get entity from DB
Out to page with all fields(fields which user shoudnt change outed as hidden inputs)
Take entity by post method
Attach to context and save
In this case i need to out on page useless fields. And it is sucks no doubt.
b)
Get entity from DB
Out to page only necessary fields(fields which user can change)
Take entity by post method
Get entity from DB
Fill DB entity by new values and save
In this case i need to do additional query to DB. So it is not good for perfomance.
What is right way?
or C):
Get entity from DB
Map entity to ViewModel with only the allowed fields
Post ViewModel with data back to controller
Map ViewModel back to Entity
Attach and Save.
EDIT:
I highly recommend AutoMapper for the mapping to and fro
Interestingly enough, I just watched a video made by Julie Lerman in which she discusses almost the exact same problem. Neither of your solutions was what she went with:
Have a separate entity class that contains the fields that you want to go on the screen, but still maps to the same table that the regular one does. Then just query that DbSet for grabbing the entity (with only those fields), and save the updates to that.
She mentioned this while discussing implementing Domain Driven Design on top of Entity Framework. So that if you have different DbContexts for different functions in your application, you can still have a DbContext that you're using write to the table, but you can restrict which fields that context can write to.
It is recommended to use different ViewModels for different tasks. If you want to show the user some fields of the Model to edit, then you can do so using EditModel and while saving use CreateModel to create and populate the database. This way you can avoid your database structure to be known to the user, thus ensuring protection and security.
We are using the Code-first approach without an Edmx file, its running fine to create database the first time.
But if I am adding new data entities say new class to my database context then it is not able to add that to new table in that database.
Say for example there are two table initially in database.
ex Database : DbTest
Table : Tbl1, Tbl2
Now if I add new table, say class name 'Tbl3', then it should be adding it into the existing database.
Can any one please explain to me with an example how it can be achieved via code first approach?
I have seen mentioned something like Database.SetInitializer(new ........)
What do I need to put in the blank area of the constructor above?
If you look in your database you will see a table called "EdmMetadata" which Entity Framework uses to determine if any changes have been made to your model since the database was created (which it has in your case).
The default behaviour is for an exception to be thrown if the model and database differ. To get different behaviour you will need to use an IDatabaseInitializer<TContext>.
Luckily, Entity Framework ships with some default implementations of this interface:
CreateDatabaseIfNotExists<TContext> - This will create the database if one doesn't already exist.
DropCreateDatabaseAlways<TContext> - This will re-create the database each time your application is run.
DropCreateDatabaseIfModelChanges<TContext> - This will re-create the database if a change is detected in the EdmMetadata table (usually as a result of creating new tables).
You can of course also create your own implementation of this interface by overriding the InitializeDatabase method.
an example of using one of these initialization strategies is shown below:
Database.SetInitializer(
new DropCreateDatabaseIfModelChanges<NameOfYourDbContextClass>())
Think carefully before choosing an initialization strategy as you could end up losing data already entered into the database and this may not be what you want.
The implementations provided by Entity Framework provide a Seed method for loading your database with data so that you can preload your database with default data each time it is created.
This article provides further information.