0

I am trying to learn C# coming from a classic ASP/VBScript background.

Up front (just in case someone can answer without all the following background info and code) - My DbContext interface doesn't allow me to do this:

_dbcontext.Entry(model).State = EntityState.Modified;

It balks at me trying to use the Entry method with the following error:

'MyNamespace.Models.IMyDataContext' does not contain a definition for 'Entry' and no extension method 'Entry' accepting a first argument of type 'MyNamespace.Models.IMyDataContext' could be found (are you missing a using directive or an assembly reference?)

How can I properly define my interface so that it will include the Entry method from the DbContext class?

BACKGROUND

I had someone who (supposedly) knows their stuff help me get the following code setup for connecting to MSSQL or MySQL based on data we retrieve from a common connection info table. The schema in MSSQL and MySQL is identical for the data model.

public interface IMyDataContext
{
     DbSet<MyModel> ModelData { get; set; }
}

public class dbMySQL : DbContext, IMyDataContext
{
     protected override void OnModelCreating(DbModelBuilder modelBuilder)
     {
          var table = modelBuilder.Entity<MyModel>().ToTable("tablename");
          table.HasKey(t => t.Id);
          table.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
          table.Property(t => t.Key);
          table.Property(t => t.Value);
          base.OnModelCreating(modelBuilder);
     }
     public dbMySQL(DbConnection existingConnection, boolcontextOwnsConnection) : base(existingConnection, contextOwnsConnection) { }

     public DbSet<MyModel> ModelData { get; set; }
}

public class dbMSSQL : DbContext, IMyDataContext
{
     protected override void OnModelCreating(DbModelBuilder modelBuilder)
     {
          var table = modelBuilder.Entity<MyModel>().ToTable("tablename");
          table.HasKey(t => t.Id);
          table.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
          table.Property(t => t.Key);
          table.Property(t => t.Value);
          base.OnModelCreating(modelBuilder);
     }
     public dbMSSQL(string connectionString) : base(connectionString) { }

     public DbSet<MyModel> ModelData { get; set; }
}

Using the above code, I have been able to successfully grab connection info from a table and return a DbContext as follows:

    private IMyDataContext selectDbProvider(int Id)
    {
        // Get database connection info
        var connInfo = _db.ConnModel.Find(Id);
        string dbProvider = connInfo.dbType.ToString();

        IMyDataContext _dbd;
        if (dbProvider == "MySql.Data.MySqlClient")
        {
            var connectionStringBuilder = new MySqlConnectionStringBuilder();
            connectionStringBuilder.Server = connInfo.dbServer;
            connectionStringBuilder.UserID = connInfo.dbUser;
            connectionStringBuilder.Password = connInfo.dbPassword;
            connectionStringBuilder.Database = connInfo.dbName;
            connectionStringBuilder.Port = 3306;
            _mysqlconn = new MySqlConnection(connectionStringBuilder.ConnectionString);
            _dbd = new dbMySQL(_mysqlconn, false);
        }
        else
        {
            var connectionStringBuilder = new SqlConnectionStringBuilder();
            connectionStringBuilder.DataSource = connInfo.dbServer;
            connectionStringBuilder.UserID = connInfo.dbUser;
            connectionStringBuilder.Password = connInfo.dbPassword;
            connectionStringBuilder.InitialCatalog = connInfo.dbName;
            _dbd = new dbMSSQL(connectionStringBuilder.ConnectionString);
        }

        return _dbd;
    }

Using all of the above, I can successfully access data in either MySQL or MSSQL:

    _dbd = selectDbProvider(Id);
    model = _dbd.ModelData.ToList();

However, when I try to do an update operation, I get the error message I mentioned at the top. How can I properly define my interface so that it will include the Entry method from the DbContext class?

2
  • I think it would make more sense for this purpose to use a factory instead of trying to implement it as interface. In other words, you would just have a class that with a method like GetContextFor(Id), that would simply return an instantiated version of your application's context with the appropriate provider set. Commented Jun 17, 2016 at 17:10
  • Chris, I removed IMyDataContext so that the MySQL and MSSQL DbSet builders now only derive from DbContext. Then using my existing selectDbProvider function, I changed it to return a DbContext instead of IMyDataContext. However now when I try _dbd.ModelData it does not recognize it - System.Data.Entity.DbContext does not contain a definition for ModelData. Commented Jun 20, 2016 at 16:18

1 Answer 1

1

Add a method to your interface for it.

DbEntityEntry Entry(Object entity)

https://msdn.microsoft.com/en-us/library/gg696238(v=vs.113).aspx

EDIT:

public class dbMyContext : DbContext
{
    //snip

    public dbMyContext(DbConnection existingConnection, boolcontextOwnsConnection) : base(existingConnection, contextOwnsConnection) { }

    public dbMyContext(string connectionString) : base(connectionString) { }

    //snip

}

Adjust your selectDbProvider class to use dbMyContext instead of dbMySQL and dbMSSQL.

Now you're using an O/RM properly. :)

Sign up to request clarification or add additional context in comments.

10 Comments

Hmm, I added exactly what was shown on that page and it says "The modifier 'public' is no valid for this item" with the blue line under the method name Entry.
Yes, you can't have modifiers in interfaces. Take out the public and it should be happy.
That worked! Apparently my reputation isn't enough to successfully vote up your answer. Thanks!
You should still be able to select it as the answer. I'm glad I could help!
I did, it just doesn't contribute to the score I guess. Thanks again.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.