Is it possible to read and write to a SQL Server database using DataTable with Entity Framework?
I have multiple code tables defined in my database such that each of them share a fixed set of properties as shown in the sample below.
For example
public class CTGender
{
public Guid ID { get; set; }
public string Description { get; set; }
public string DisplayValue { get; set; }
//...Other properties specific to CTGender
}
public class CTNationality
{
public Guid ID { get; set; }
public string Description { get; set; }
public string DisplayValue { get; set; }
//...Other properties specific to CTNationality
}
The situation I face right now is the ever expansion of my code tables, could be another CTCountry, CTRole and so on, for example.
I am trying to synchronise these code tables between multiple databases.
The solution is heavily dependent on Entity Framework as the data access.
Is there a generic way for Entity Framework to read and write ALL these code tables without their entity models defined, like how you can read and write generic DataTables using ADO.NET?
Yes, there are couple of ways by which you can create tables at code side then either using code first approach or using publish project mechanism you can generate tables in SQL server using entity framework.
In the latter approach, you can create a separate project where you can write SQL for your various tables. This project should target SQL Server. You can right click on this project and click on publish option for updating all your tables inside SQL server.
Related
I have an application that only need a connection to one server. However, this server have 4 different databases that the app need to interact with.
Currently "the way I know how", I would have to create a new connection string in the Web.Config file for each database. Each connection will then have a separate context class which extends DbContext. Finally, each context will have a list of the model that represent each table.
I am hoping I can use one connection and one context. In order for me to do that, I would need somehow to point the models that are not part of the default database what database they belong to.
Is there a way to change the default database name for each model? I would prefer to use annotation somehow to change it here is an example of that I am thinking.
[InitialCatalog("SecondaryDatabaseName")]
public class Site
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name{ get; set; }
public bool IsActive { get; set; }
}
I would like to get some ideas about how retrieve data from a MSSQL database with the constraints for all the columns. I'm listing all the databases on a server, and let the user choose the database, and after that, let them choose a table to CRUD against. This is going to be shown in a javascript grid (Slickgrid) for inline editing.
It's going to be very close to what you get when you rightclick a table in MSSQL Management Studio and select Edit top 200
Chalenges:
The application should access a bunch of different databases that often change, so generating POCOs is out of the question. The databases are also very often porly made and does not contain FKs as they should.
I do need to have some server side validation, and preferably client side as well for all the columns, so I do need to get the information about datatype, nvarchar length, nullable or not and so on from the DB.
I'm used to program in C# with EF/ADO.NET, but i would not mind trying some other languages like Node.js, if there are any good support for what I'm after (Not interested in PHP though).
I was thinking about using ASP.NET MVC with ADO.NET and read the data into some models like this:
public class GridVM
{
public IEnumerable<Column> ColumnDefinitions { get; set; }
public IEnumerable<dynamic> Rows { get; set; }
}
public class Column
{
public string Name { get; set; }
public string Type { get; set; } //perhaps public Type Type?
public bool Nullable { get; set; }
public int MaxLength { get; set; }
}
And then creating a list of dynamics with the number of properties corresponding with the number of entries in the ColumnDefinitions.
dynamic
{
public object column1 { get; set; }
public object column2 { get; set; }
public object column3 { get; set; }
//etc, so that I get properties for all the columns
}
I do have some code for binding retrieved data from a DataReader to a data model, ignoring the property names not corresponding with the column names, but I need to do it without having a known data model.
The questions:
Is this a good approach or should i reconsider using some other technique or method? Are there any pitfalls with this approach that I'm not seeing right now?
I am very new to ASP.Net and MVC applications so pardon me if this question has been asked or is trivial.
I know how to create an entity model class from a database table, but I want to perform a series of Joins and create a Pivot table from an SQL query and then pass this to a view.
However, I do not know a quick way to create an entity class for this.
Currently, I am doing it the long way by manually defining a model class like so:
public class OAData
{
public int Zone { get; set; }
public string Device { get; set; }
public string Part { get; set; }
...
//CONSTRUCTOR
public OAData(int zone, string device, string part...){
Zone = zone;
Device = device;
Part = part;
...
}
}
and then create a database connection in the controller, loop through all the records, creating OAData objects for each record, add it to a list and then pass that list to the View.
Is there an easier way to do this (there are many fields returned by the query)? Can I create a model from a complex SQL query rather than just off a database table?
Just recently tried OrmLite for MySql in a C# console project:
I'm loving it, since it's easy to implement with MySql, in contrast to Entity Framework. However I'm trying to enable automatic updates of the database schema from my model. I extended the code given in the answers in:
With OrmLite, is there a way to automatically update table schema when my POCO is modified?
And came up with a solution that can add and delete columns in your database schema, depending on the model. Works pretty good, and utilizes a lot of the features OrmLite.ModelDefinition gives.
See the solution here:
https://github.com/contradel/Extending-NServiceKit.OrmLite
However I can't get it to automatically create foreign keys with GetDialectProvider.ToAddForeignKeyStatement(). And I can't find any documentation. Does anyone know how it works?
I would like to be able to do this:
public class Order
{
//Try to add or comment out properties here, SQL will be generated automatic
[AutoIncrement]
public int Id { get; set; } //pk
public DateTime? OrderDate { get; set; }
[References(typeof(Customer))] //Creates Foreign Key
public int CustomerId { get; set; }
}
And then:
foreach (FieldDefinition field in missingOnDb)
{
//if (field != ForeignKey)
var addSql = string.Format(db.GetDialectProvider().ToAddColumnStatement(typeof(T), field));
//else
//addSql = db.GetDialectProvider().ToAddForeignKeyStatement(??,??,??,??,??);
Console.WriteLine(addSql);
db.ExecuteSql(addSql);
}
Any help or advice regarding this issue is greatly appreciated.
I am currently working on a project that requires a change in our data layer from a local MS SQL instance to a hosted Oracle solution.
Previously, we were using Entity Framework (Code-First) to build our data layer. I would like to take the same approach with the new data layer. We have several applications that use this library, so trying to keep the new data layer as close to the same (objects, names, etc.) as the original would be ideal. I know that Code-First is not officially supported by Oracle (a work in progress), but have read where others have had some success. Thus, for these reasons, I am attempting to do the same.
I have created my Oracle EF data layer to match as closely as I can to the original MS SQL EF data layer. The issue that I'm currently having is that when I run a query to retrieve the first or default entity from the data layer, I get the following exception:
Oracle.DataAccess.Client.OracleException: ORA-00942: table or view does not exist
If I use the exact same DbContext instance and instead run a sql query using the DbContext.Database.SqlQuery(sqlString), it works. The reason I mention this is because I've read the "table or view does not exist" error refers to a database permissions issue. That does not appear to be the case this time, since I'm using the exact same connection string in the same connection object. The only difference appears to be in using traditional sql statements versus the DbSet entities (& configurations).
My entities are relatively simple, flat objects.
public class HourlyPrice
{
public DateTime MarketDate { get; set; }
public int HourEnding { get; set; }
public string LocationId { get; set; }
public string LocationName { get; set; }
public decimal? Price { get; set; }
public int IsValid { get; set; }
public DateTime DateInserted { get; set; }
public DateTime? DateUpdated { get; set; }
}
public HourlyPriceConfiguration(string viewName)
{
ToTable(viewName);
HasKey(x => new { x.MarketDate, x.HourEnding, x.LocationName });
Property(x => x.Price).HasPrecision(13, 6);
HasEntitySetName("SourceHourlyPrices");
}
Inside my DbContext, I add the HourlyPriceConfiguration injecting the viewName ...
modelBuilder.Configurations.Add(new HourlyPriceConfiguration(this.viewName));
... and declare my IDbSet as ...
public IDbSet<HourlyPrice> SourceHourlyPrices { get; set; }
When running the code, this works ...
var sql = "select * from " + this.viewName;
var prices = db.Database.SqlQuery<HourlyPrice>(sql);
var price = prices.FirstOrDefault();
... but this ...
var price = db.SourceHourlyPrices.FirstOrDefault();
... produces the "table or view does not exist" error.
Is this just an issue with the Code-First approach, or am I missing something here? When debugging the application, I can see the viewName being passed to the configuration class is the same that is being passed to the sql statement used in SqlQuery. I've tried removing the HasEntitySetName() and changing the IDbSet to the standard HourlyPrices, but that didn't work, either.
Thanks again, in advance.
I would like to confirm that I had the same problem with a table name.
In Oracle if the name is not full UPPER CASE the table/view is not found.
Code First Automatic Migrations is limited to working with the dbo schema only.
https://community.oracle.com/thread/3622163
You can put it in beginning OnModelCreating method of your Context class as a workaround.
if (this.Database.Connection.GetType().Equals(typeof(Oracle.ManagedDataAccess.Client.OracleConnection)))
{
modelBuilder.HasDefaultSchema(new Oracle.ManagedDataAccess.Client.OracleConnectionStringBuilder(this.Database.Connection.ConnectionString).UserID);
}
The ORA-00942 exception is not a permission issue (depends on how you look at it of course); but it means that the table you are querying is not visible to your user.
You may try to explicitly set the name of your schema in your ToTable method call by using the ToTable(tableName, schemaName) implementation and see what happens.
Just wanted to add that I had the same problem after moving the DB to a different schema. I realised that it is critically to have the schema name in upper case when using ToTable(tableName, schemaName).