I am working on a project where I may not alter the database in any way (unfortunately). I have started the project using Entity Framework and this has worked for the first few objects that I need. Now I have come across two scenarios that I am not sure how to accommodate.
Tables without a primary key defined.
Tables using the suffix of the table name as a field.
For the first, I get an error about reviewing my schema and uncommenting the proper area of the edmx file. The table has a field that acts as primary key but is not designated as not null and does not have a primary key created for it.
For the second, there are several tables with names like order1, order2, order3 etc where the table that needs to be accessed would be a parameter of my access methods.
My thought is that it would be simplest to just manually write the SQL and bind the data to models. If I go that route would I even use EF or do I just create a new database connection? what would be the 'proper' way to go about that?
Related
I'm setting up a data warehouse (in SQL Server) together with our engineers we got almost everything up and running. Our main application also uses SQL Server as backend, and aims to be code first while using the entity framework. In most tables we added a column like updatedAt to allow for incremental loading to our data warehouse, but there is a many-to-many association table created by the entity framework which we cannot modify. The table consists of two GUID columns with a composite key, so they are not iterable like an incrementing integer or dates. We are now basically figuring out the options on how to enable incremental load on this table, but there is little information to be found.
After searching for a while I mostly came across posts which explained how it's not possible to manually add columns (such as updatedAt) to the association table, such as here Create code first, many to many, with additional fields in association table. Suggestions are to split out the table into two one-to-many tables. We would like to prevent this if possible.
Another potential option would be to turn on change data capture on the server, but that would potentially defeat the purpose of code first in the application.
Another thought was to add a column in the database itself, not in code, with a default value of the current datetime. But that might also be impossible / non compatible with the entity framework, as well as defeating the code first principle.
Are we missing anything? Are there other solutions for this? The ideal solution would be a code first solution, or a solution in the ETL process without affecting the base application, without changing too much. Any suggestions are appreciated.
I have a DataSet with multiple tables the source document is an XML file.
mydataset.ReadXML(filename);
There are multiple tables with multiple relations. I have the database in the SQL created via code - tables, columns and relations.
Now I would like to insert the data . (Yes I want everything).
EDIT: The SQL tables use Identity Columns autogenerate - because I am not sure the incoming data will never duplicate one of the parameters that I would like to assume is unique.
So what methods should I do to ensure data is input considering I have foreign key constraints , how should I iterate the the tables in the dataset to make sure I don't try to insert in tables requiring an existing id. Do I create a hard coded map (I prefer not too) , or do I walk the tables looking for a Foreign key and verify the parent table etc..
Any Ideas ? I am sure someone has done this before and has a simple answer for me.
You have a couple of options. Assuming the database is not generating the key values, this is pretty simple. Either
1) You discover the order to load the tables so that each table with a Foreign Key is loaded after the table to which it refers.
2) You turn off constraint checking in SqlBulkCopy, and then optionally check the constraints after loading.
To check the constraints after load, run a command like
alter table SomeTable with check check constraint fk_SomeTable_OtherTable
If you do have database-generated keys, this is all harder. But the best way to tackle that is to use SEQUENCE objects isntead of IDENTITY columns and run sp_sequence_get_range to fetch the new key ranges to the client and apply the keys there first.
I am building an Ntier application with EntityFramework c#.
I am adding an Entity Data Model in my Data Access Layer with code-first approach from existing database.
Some of the tables of my db weren't included because they don't have primary key. I have seen some ways to work around this problem, modifying EntityFramework's edmx to force the mapping to the database, disguising some field like a key. But I am not using the .edmx, since I can't use automatic migrations with it. I only generate POCOs from my existing database and then go on with code first migrations.
Is there a way to force Entity Framework to generate a POCO for those tables without primary key ? Some only have one entry and really don't need PrimaryKey
In the end, I just wrote my own POCOs for the tables that weren't included.
I used an attribute [KEY] above the property i wanted to act like key. I added DbSet lines in the DataModel and EF did recognize them in my database.
I didn't want to generate primary keys because my boss didn't want, and thats a reason good enough. :) Hope the best for you thx for answer
We have a system that will use the same code to communicate with different client databases. These databases will use the same EF Model, but different connection strings.
Our problem is, not every site will be using the same version of our database structure; some might be missing a few columns or contain a few old columns.
If we upgrade the system to the current version, now the database model now has an extra EmergencyContact column. All older databases will now fail, because EF is trying to insert into this column (even though we have not set a value for this property).
Is there a way of telling EF to only use columns for which we have a value for, when it generates the INSERT INTO query?
EF will be fine if your schema has missing columns that are in the real database, but it will not work if you have columns in the schema that are not in the database, and there is no way to fix that.
Your only choice is to use different schemas for different databases, and write code that manages them (ie, only instantiates the version of the context you need).
In the case where your model does not match your database schema, EF will only insert/update the columns in the model. However, if the unknown columns are not null, EF will throw an exception. Also, if you created relational constraints on the unknown columns, of course those will not be created as they are not yet known.
If the persistence layer per site is the only part that changes then I would extract your EF model into it's own version e.g.
DbV1.dll
DbV2.dll
You could then load in the appropriate DLL based on some setting from the client i.e. you could pass information as a custom header e.g.
db-version: 1
There are other more reliable ways, however, I don't know what your current setup is like so it's difficult to answer.
I'm building a small db-cleaner app for a QA sql server database. Naturally, I need to delete table rows with dependencies on them.
T-SQL cascading abilities are very limited, so I've tried using NHibernate to simplify matters. But, the only way I found for this was to create a collection for each dependency
in the object-to-delete, and mark that as cascade=delete.
That means creating many, many collections (both in the hbm file and in the C# object) which I don't need for any other purpose. Which makes this method as complicated as just using SQL.
Am I missing something? Is there any easier, more generic way to perform delete-cascade?
Thanks.
EDIT: Just to be clear, I avoid changing the foreign keys in the DB because it's a QA DB, designed to be identical to the production DB.
Eventually I found out a generic way to do the deletion:
This guy wrote a recursive SP which does all the work for you:
http://www.sqlteam.com/article/performing-a-cascade-delete-in-sql-server-7
Needed a little touch-ups (since my DB uses schemas) but works like a charm.
I suppose you have foreign keys defined between related tables in your database ?
You can specify at the foreign key level what should happen with related records when a parent record is being removed.
Check out MSDN for the cascading options, and how to define them:
Cascading FK constraints
Foreign Key Constraints