SQLite code-first onModelCahnge how to keep the old data from databse - c#

i'm new to Sqlite and EF.
i created a DbContext with some model classes which will create a local database on app start. Database will get updated while application running.
When i change something in model (ex: add new property to a class) and run the application, the whole database is recreating from scratch. so i'm loosing my saved data.
How can i keep the old data even though the model changes.
For Ex:
Database.table1
ID | Name
1 | abc
2 | xyz
when i add new prop to table1 class, its recreating table with empty data, where i need something like this if possible.
Database.table1
ID | Name | NewProp
1 | abc | Null
2 | xyz | Null

The database initializer is what causes the database to be recreated on a model change. So you can disable the initializer by setting it to null:
Database.SetInitializer<MyContext>(null);
This of course means you will need to manually make your database match the model. Another option is to use an initializer that doesn't drop and create the database. Looks like there is a project here for SqlLite: https://github.com/msallin/SQLiteCodeFirst So then you could use SqliteCreateDatabaseIfNotExists.
Finally, you could use migrations. Doesn't look like that's supported out of the box so you would need a third party tool for that. Entity Framework MigrationSqlGenerator for SQLite

Related

Map stored procedure with multiple resultset returned in EF Core

I am currently migrating an already established website from old ASP.NET to ASP.NET Core 2.2. The database is a shared database across other platforms and is also established therefore I cannot just changed anything from it.
I came across to this problem when I had to call a stored procedure from EF Core where this stored procedure returns 3 result sets. The result set of the stored procedure is like this.
Table 1
ColumnName1 | ColumnName2 | SomeColumn | AndMoreColumns
------------+-------------+------------+---------------
Value1 | value 2 | value 3 | Value 4
Table 1
Column1 | Column2
-----------+----------
value1 | value 2
Table 3
Column1
-------
Value1
Table 1 and table 2 are related to each other. This table will always return 1 row on table 1 and table 2 can return multiple rows while table 3 is static.
Now, my question is. How do I map this result set to an EF Core Query<T> model builder? I want to map it per column name since I want to make the column names more friendly. An example that I had that did not work is like this.
modelBuilder.Query<MyModel>(a =>
{
a.Property(b=>b.ModelId).HasColumnName("ColumnName1");
a.Property(b=>b.ModelName).HasColumnName("ColumnName2");
...
});
but unfortunately, the above mapping did not work. Especially for the 2nd table.
First at all, the result from stored procedure is not a table, I mean an user table.
So, I think there are two possible solutions for your question:
Work with pure ADO.NET, execute data reader and cast the result to result models
Use an external approach from EF Core
For point 1, please read this question: EF Core query stored procedure map to types
For point 2, please read this question: Working with multiple resultset in .net core
Also you can read this issue: Support multiple resultsets #8127
Let me know if this answer is useful.
You might want this post until EF Core implement similar function:
https://www.danylkoweb.com/Blog/aspnet-core-with-entity-framework-core-returning-multiple-resultsets-OL

Entity Framework 6 mapping a custom SQL query to an Entity

I am very new to ASP.NET MVC and Entity Framework at the moment. I've been working with it for about 3 months at the current moment in time.
I have an ASP.NET MVC 5 application that's running Entity Framework 6. This is a code first approach from an existing database with auto migrations enabled so all of my Entity classes are auto generated. I am trying to add a view to my MVC application that returns a specific result set. Currently the previous developer has the application set up to only accept an Entity class to display data to a DataTable DataTables.net. To clarify further:
I have two Entity tables in my model that are tables in MySQL.
| Samples | SampleLocation |
|:------------------|---------------:|
| Id | LocationId |
| DateAssigned | Name |
| CheckedInDate | Size |
| SampleLocationId | |
| ...etc | ...etc |
What I'm trying to accomplish is querying both tables and returning the results to my MVC application in a view. From there run an Update and update a couple of columns in the Samples table. Below is the roughly the query that returns the results I need.
SELECT Samples.Id, samples.CheckedInDate, SampleLocation.Name, SampleLocation.Size,
SampleLocation.LocationId
FROM (Samples join SampleLocation
ON ((Samples.SampleLocationId = SampleLocation.LocationId)))
WHERE isnull(samples.CheckedInDate) ORDER BY samples.Id
From the research that I have done there are a few ways to accomplish this. The ways that I've tried that would give me a class I could use are creating a stored procedure and then updating the model - this breaks the model and unmaps every single entity in the model. I have tried creating a view with the query to add to the model - but this breaks it as well and unmaps everything. I later found out that this is a bug.
So my question is, how can I map a query to an Entity that return results to a view? Is there a better way to go about this?
There are several ways to accomplish what you want to do, using either Entity Framework only or extra tools like Dapper
Entity Framework Only:
First you can use Linq to extract the data, I'll look something like this:
var list = from s in Samples
join l in SampleLocations
on s.Id equals l.LocationId
where s.CheckedInDate == null
select new
{
s.Id,
s.CheckedInDate,
l.Name,
l.Size,
l.LocationId
};
Dapper:
The second method is using dapper, the only real difference here is that you would be working with your queries directly, so instead of linq you had something like this:
Connection.Query(#"SELECT Samples.Id, samples.CheckedInDate,
SampleLocation.Name, SampleLocation.Size,
SampleLocation.LocationId
FROM Samples
join SampleLocation
ON Samples.SampleLocationId = SampleLocation.LocationId
WHERE isnull(samples.CheckedInDate) ORDER BY samples.Id");
For both:
In your update method, you first have to retrieve the entities, for that you can use the DbSet.Find method or another query, after that you call DbConext.SaveChanges.
This is the solution to my problem. Basically manually creating an Entity within the XML and mapping it to a virtual table.Entity Framework DefiningQuery

Migrating from Nhibernate to EF6

I currently have an .NET application that has a SQL Sever database with GUIDs for Primary Keys. We are using NHinbernate for the ORM but want to switch to the latest version of Entity Framework and use Identities(INTs) as our Primary Keys.
Does anyone have any experience or references that will help me in making this transition? Whats the easiest way to migrate the data and implement the new ORM?
If you are choosing to use int keys because of migrating to EF, you actually don't need to change it, and you can keep the existing data, have a look at this.
But if you need to move to int keys for some other reason, it's going to be hard and not that easy. One thing about GUID is it's never duplicate, so you can do something like this,
Export all the GUID's in the current structure (assume table name as key_table) and insert into a table in the new database with auto generated id. Something like this,
--------------------------------------------------
| Id | OldKey |
--------------------------------------------------
| 1| 3d09565d-eb84-4e9c-965c-d530c1be8cf2 |
--------------------------------------------------
| 2| 54a93dbc-7ce8-4c88-a8e0-70cc48a84073 |
--------------------------------------------------
When you do insert, you can fetch the key from this table using a select statement. wherever you need a primary key or a foreign key, something like this,
SET IDENTITY_INSERT User_Table ON;
Insert into User_Table (Id,RoleId,UserName,...)
VALUES (select id from key_table where OldKey = '3d09565d-eb84-4e9c-965c-d530c1be8cf2'),(select id from key_table where OldKey = '54a93dbc-7ce8-4c88-a8e0-70cc48a84073'),'User 1',...);
SET IDENTITY_INSERT User_Table OFF;
this would be the easiest way of doing it, but the id columns would not be linear in your new database with this approach.
This is a breaking change and there is no tools available to help you with this kind of migration. Your best bet would be to stick to NHibernate. If you must change, you'll need to manually write a data migration tool yourself.

Altering the database at runtime with Entity Framework & Code First

Is there any way to alter the underlying database using EF using Code First approach?
I have 2 tables which have a static model:
Users and Info1.
I also have another table which Ill call info2.
I would like to be able to add and remove columns from Info2 from the admin section of my website.
My goal is to have a website which can dynamically be altered as you go, adding and removing fields as the user likes, without the user having to know anything about coding.
I've considered using a separate database outside of the one specified in the model of my MVC3 project and do straight SQL requests to that instead.
This could also be accomplished by having a table with the dynamically created fields, and another with the data, but this gets messy fast.
Has anyone done anything like this? Is it a bad idea?
I'd recommend not trying to expand the table horizontally, that's an operation that you should make a conscious decision to have.
Instead, I'd recommend that you store the values as name/value pairs. You can have tables that have specific types (let's say you needed an integer value paired with a key), and then you would select those into a dictionary for the user.
You'd also have a table which has the keys, if you are concerned about replicating key values.
For example, you'd have a UserDefinedKey table
UserDefinedKeyId (int, PK) Key (varchar(?))
-------------------------- ----------------
1 'My Website'
2 'My favorite color'
Then you would have a UserDefinedString table (for string values)
UserDefinedStringId UserId UserDefinedKeyId Value
(int, PK) (int, FK) (int, FK) (varchar(max))
------------------- --------- ---------------- --------------
1 1 1 'http://stackoverflow.com'
2 1 2 'Blue'
3 2 2 'Red'
You'd probably want to place a unique index on the UserId and UserDefinedKeyId fields to prevent people from entering multiple values for the same key (if you want that, have a separate table without the unique constraint).
Then, when you want to add a value for users, you add it to the UserDefinedKey table, and then drive your logic off that table and the other tables which hold the values.
Another benefit of storing the values vertically is that you aren't wasting space for columns with values that aren't being used by all users.
For example, assuming you take the approach of modifying the table, for the attributes above, you would get:
UserId WebSite Color
------ ------- -----
1 http://stackoverflow.com Blue
2 (null) Red
Now let's say a third user comes along, and adds a Favorite Sports Team value, and they are the only one who uses it, the table then looks like:
UserId WebSite Color FavoriteSportsTeam
------ ------- ----- ------------------
1 http://stackoverflow.com Blue (null)
2 (null) Red (null)
3 (null) (null) Yankees
As the number of users and attributes grows, the amount of sparse data that you have will increase dramatically.
Now, assuming you are using SQL Server 2008, you could use sparse columns, if you don't, your table is going to get huge but not have much data.
Also, using sparse columns doesn't take away from the fact that it's pretty dirty to use data definition language (DDL) to change the schema on the fly.
Additionally, Entity Framework isn't going to be able to adapt it's object model to account for the new attributes; every time you have an attribute added, you will have to go and add the attribute to your object model, recompile, and redeploy.
With a vertical approach, it takes more work, granted, but it will be infinitely flexible, as well as utilize your database space more efficiently.

Mapping a single row table without primary key using Nhibernate

I'm working with a legacy table which I cannot change. The database have a settings table which consists of a lot of columns (one for each setting) and only one row:
Columns: Setting1 | Setting2 | Setting3 | etc...
----------+--------------+-----------+-------------
Row1: SomeValue | AnotherValue | LastValue | etc...
Now, this would be all fine if it wasn't for the fact that the table lacks a primary key. Obviously, the original developer didn't think it was necessary, as there's only one single row.
Is there any way of mapping this with Nhibernate? I've already implemented a SQL based solution, but I'd love to have the flexibility and simplicity gained with Nhibernate.
I'm fearing the worst but, any ideas?
You could map a view that adds a dummy PK column:
select 1 as SettingsId, Setting1, etc....
or load the object from a stored procedure.
Well, just pick any setting (column) as the Id. The only inconvenience is that if you need to change the setting that is the PK you'll have to delete and re-insert the row...

Categories