I'm currently trying to read data from a table out of SQL server. The table has 10 columns and when i'm reading the base table by itself, everything works out just fine.
The trouble is, there are X number of extra property tables that may or may not go with my base table. Some databases only have the base table with 10 columns, while others have property tables containing more columns that must be joined into the base table in order to properly display the needed data. Is there a way via EF6 to load that data into a queryable source in a decoupled way?
Basically due to the fact that the extra tables are constantly in flux, I cannot rely on generating models for them and using the mapping EF provides. I do have a model for the base table as its 10 columns never change. I also have a mechanism to read the relational information in order to get the names of the property tables and columns that my program needs to display with the base table when they are available.
Any insight is greatly appreciated.
Good old-fashioned ADO.NET does a good job giving you run-time access to arbitrary query results. You can examine the column data types returned in a DataReader or after loaded into a DataTable, and access columns by name or ordinal position.
And you can interop beteween EF (for your design-time models) and ADO.NET tables that vary at runtime.
Related
I inherited an application that talks to many different client databases.
Most of these tables in the client databases have identical schema - but there are a handful of tables that have extra custom columns that contain tax information (ya - bad idea - I know … I didn't set it up).
These extra columns could be named anything. They are known at runtime as they can be looked up in another table.
I can setup EF to that it will read/write these tables (skipping the dynamic columns) but I really do need this information - as it is tax data.
I think my best route it to have a fixed model with extra properties added that could be filled by these dynamic columns.
How can I get Entity Framework to dynamically read and write these columns without using custom SQL statements on every call?
I can do extra reads and writes to read and write these extra columns separately (using custom sql)… but there must be some way to override EF so that it knows about these extra columns and can handle them correctly.
Any help would be appreciated.
In a first step, you could interrogate the _INFORMATION_SCHEMA_, or other metadata tables directly, to know if the table you want your context to be on has these columns. Based on that information, you can use a different DbContext (generic would probably work) but create it using MappingConfiguration in which you either ignore the columns if they aren't there, or map them to the POCO class your context desires.
Sorry if my question is basic, when we use ADO.net to write own data access code, and we work with more than of one data table, data relation between data tables comes automatically from data base tables or we have to add data relation between data tables separately.
To understand Data Relation in Ado.Net you can read This.
when you work with more than of one data table then you can either write code yourself(using DataRelation),The DataSet contains DataTable objects and DataRelation objects. The DataRelation objects represent the relationship between two tables or you can use ERD(entity Relationship Diagram) to drag and show relationship among tables.
In my opinion database diagram is better as it reduces or exempt you do do extra code work, but manual code adds flexibility and customization.
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've been asked by my boss to replicate an MS Access feature that we're going to lose shortly after migrating our product to .NET.
The feature is the ability to view and update any data in the database, particularly Tables or Views, in a tabular grid.
I can do it for pure tables that have a identity column because the SqlDataAdapter can auto-generate the relevant CRUD methods on the fly, to fill / update via DataTables.
However, views are somewhat more tricky. SQL Server Management Studio does allow it. If you click 'Edit top xx rows' on a View, it allows you to edit the data in some columns in what looks to be a standard .NET DataGridView - though it feels a bit magical.
So, a few questions:
How does SSMS infer which primary key to use, even if the key is not in the view?
How does SSMS determine which column inside a view can or can not be edited / inserted / deleted etc.?
What would be my best option to replicate this inside a .NET application?
Is it possible to connect a DataGridView to an old style oledb / obdc connection that has a constant direct connection to the database?
Any guidance as normal will be highly appreciated.
Marlon
SQL Server views can be updated just as if they were a single table, as long as they conform to certain conditions.
From the documentation:
Updatable Views
You can modify the data of an underlying base table through a view, as
long as the following conditions are true:
Any modifications, including UPDATE, INSERT, and DELETE statements,
must reference columns from only one base table.
The columns being modified in the view must directly reference the
underlying data in the table columns. The columns cannot be derived in
any other way, such as through the following:
An aggregate function: AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV,
STDEVP, VAR, and VARP.
A computation. The column cannot be computed from an expression that
uses other columns. Columns that are formed by using the set operators
UNION, UNION ALL, CROSSJOIN, EXCEPT, and INTERSECT amount to a
computation and are also not updatable.
The columns being modified are not affected by GROUP BY, HAVING, or
DISTINCT clauses.
TOP is not used anywhere in the select_statement of the view together
with the WITH CHECK OPTION clause.
The previous restrictions apply to any subqueries in the FROM clause
of the view, just as they apply to the view itself. Generally, the
Database Engine must be able to unambiguously trace modifications from
the view definition to one base table. For more information, see
Modify Data Through a View.
I don't believe SSMS is doing anything special - editing the contents of a view offers exactly the same functionality as editing the contents of a table. If the user attempts to make a change that does not conform to the above conditions, SSMS will likely display an error.
How does SSMS infer which primary key to use, even if the key is not in the view?
It doesn't. SQL Server does since only one underlying table can be edited at a time.
How does SSMS determine which column inside a view can or can not be edited / inserted / deleted etc.?
Again, it's SQL Server that determines this, not SSMS.
What would be my best option to replicate this inside a .NET application?
As long as all your views conform to the above conditions, simply do the same as you're doing for tables, but be ready to handle the errors from users doing something they can't (this implies some user training will be required, just as it would be if they were using SSMS directly).
Is it possible to add fields to an entity framework class that rather than being mapped to a column in a table instead map to a SQL query?
For a contrived example (NB: This is not what I'm actually trying to do just an easier to explain example of what I'm trying to accomplish) I want my class to have a TableCount field that holds the result of SELECT COUNT(*) FROM MyTable at the time the object was loaded from the db.
EDIT: I should have mentioned this in my original post but I'm using POCO classes.
You cannot do it directly with entity mapped to a database but there are two ways how to achieve it with a new entity type containing columns from your original entity and your additional computed columns:
Create database view and map that view - this is fully automatic way maintained by EDMX designer for you
Write query to populate whole new entity type and map it manually in DefiningQuery. The disadvantage is that it requires manual EDMX editing and without additional (commercial) tool also manual maintenance of EDMX because standard VS EDMX Designer overwrites edited SSDL part every time you select update from database.