tag:support.appharbor.com,2010-11-23:/discussions/problems/2106-connecting-to-sequilizer-with-code-first-entity-frameworkAppHarbor: Discussion 2012-01-19T00:20:14Ztag:support.appharbor.com,2010-11-23:Comment/129555552012-01-17T02:01:37Z2012-01-17T02:01:37ZConnecting to Sequilizer with Code First Entity Framework.<div><p>I've been trying to get the db connection to work for my app for
a few days now. I followed the directions on the documentation site
about putting in the db alias as follows:<br></p>
<pre>
<code><add name="TrulySkilledContext"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=TrulySkilled.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True"
providerName="System.Data.SqlClient"
/></code>
</pre>
<p>(that connection string is for my local machine obviously), but
every time I deploy the application I get the error <code>The
provider did not return a ProviderManifestToken string. --->
System.Data.SqlClient.SqlException: A network-related or
instance-specific error occurred while establishing a connection to
SQL Server. The server was not found or was not accessible. Verify
that the instance name is correct and that SQL Server is configured
to allow remote connections. (provider: SQL Network Interfaces,
error: 26 - Error Locating Server/Instance Specified)</code></p>
<p>I saw the post about writing your own custom connection string
based off the appSettings variables that get injected into your
application, but I still get the same error. What am I doing
wrong?</p>
<p>Thanks for your time!</p></div>nadreestag:support.appharbor.com,2010-11-23:Comment/129555552012-01-17T02:05:46Z2012-01-17T02:05:46ZConnecting to Sequilizer with Code First Entity Framework.<div><p>Have you specified <code>TrulySkilledContext</code> as the alias
on sequelizer?</p>
<p>Michael</p></div>friismtag:support.appharbor.com,2010-11-23:Comment/129555552012-01-17T02:07:22Z2012-01-17T02:07:22ZConnecting to Sequilizer with Code First Entity Framework.<div><p>Yes I did, and I left the metadata portion blank because it's
Code First (I think that's correct...)</p></div>nadreestag:support.appharbor.com,2010-11-23:Comment/129555552012-01-17T02:13:19Z2012-01-17T02:13:19ZConnecting to Sequilizer with Code First Entity Framework.<div><p>Have you verified that your database still exists? EF has a
tendency do drop it, and you need to use this nuget package:
<a href=
"http://nuget.org/packages/EFCodeFirst.CreateTablesOnly">http://nuget.org/packages/EFCodeFirst.CreateTablesOnly</a></p>
<p>Michael</p></div>friismtag:support.appharbor.com,2010-11-23:Comment/129555552012-01-17T02:20:51Z2012-01-17T02:20:51ZConnecting to Sequilizer with Code First Entity Framework.<div><p>I can connect to the database using the Server Explorer in
Visual Studio, and I still see the tables after doing a
refresh.</p>
<p>I have installed the NuGet package and it put a class is my
App_Start folder:</p>
<pre>
<code>public static class DontDropDbJustCreateTablesIfModelChangedStart {
public static void Start() {
// Uncomment this line and replace CONTEXT_NAME with the name of your DbContext if you are
// using your DbContext to create and manage your database
Database.SetInitializer(new DontDropDbJustCreateTablesIfModelChanged<TrulySkilledContext>());
}
}</code>
</pre>
<p>I think that's all I needed to do to make that package work
right?</p></div>nadreestag:support.appharbor.com,2010-11-23:Comment/129555552012-01-17T03:05:04Z2012-01-17T03:05:04ZConnecting to Sequilizer with Code First Entity Framework.<div><p>Yeah, sounds like you should be all set.</p>
<p>You might want to use this method to see if you can figure out
why your application is not using the expected connectionstring:
<a href=
"http://blog.appharbor.com/2011/12/20/super-simple-logging-on-appharbor">
http://blog.appharbor.com/2011/12/20/super-simple-logging-on-appharbor</a></p>
<p>Michael</p></div>friismtag:support.appharbor.com,2010-11-23:Comment/129555552012-01-17T18:08:25Z2012-01-17T18:08:25ZConnecting to Sequilizer with Code First Entity Framework.<div><p>Thanks, I'll look into this when I get home tonight. If I dump
the connection string from the WebConfigurationManager I should see
the Sequelizer connection string right? Is there anything else that
you think I should be looking out for?</p></div>nadreestag:support.appharbor.com,2010-11-23:Comment/129555552012-01-17T19:19:48Z2012-01-17T19:19:48ZConnecting to Sequilizer with Code First Entity Framework.<div><p>I think you can also get the connectionstring Entity Framework
is currently using off the context, you should do that too.</p>
<p>Michael</p></div>friismtag:support.appharbor.com,2010-11-23:Comment/129555552012-01-18T21:57:12Z2012-01-18T21:57:12ZConnecting to Sequilizer with Code First Entity Framework.<div><p>I managed to get the app working by hard coding the connection
string into the DbContext. It's not the best way but it works for
now. Does the connection string replacement not get inject until
the app has actually been deployed (this could cause my issues with
the tests not being able to connect)?</p></div>nadreestag:support.appharbor.com,2010-11-23:Comment/129555552012-01-18T22:03:58Z2012-01-18T22:03:58ZConnecting to Sequilizer with Code First Entity Framework.<div><p>I tried the message you suggested, but the app isn't displaying
any log<br>
messages in the Errors page. Could this be because the app is
failing<br>
during the unit tests (that's when it's trying to connect to the
database)?</p>
<p>Thanks,<br>
Nathen Drees<br>
Iowa State Engineering<br>
Software Engineering</p></div>nadreestag:support.appharbor.com,2010-11-23:Comment/129555552012-01-18T22:13:35Z2012-01-18T22:13:35ZConnecting to Sequilizer with Code First Entity Framework.<div><p>Your last messages explains everything.</p>
<p>The connectionstring is not inserted while unit tests are run.
This is because you shouldn't be using the database to execute
tests, mock the data access instead.</p>
<p>Michael</p></div>friismtag:support.appharbor.com,2010-11-23:Comment/129555552012-01-18T23:48:01Z2012-01-18T23:48:01ZConnecting to Sequilizer with Code First Entity Framework.<div><p>Thanks, I mocked them out and everything appears to be working
now.</p>
<p>Thanks for all the help.</p></div>nadreestag:support.appharbor.com,2010-11-23:Comment/129555552012-01-18T23:49:06Z2012-01-18T23:49:06ZConnecting to Sequilizer with Code First Entity Framework.<div><p>No problem, I'm happy we found the cause! I'll add this to the
FAQ now.</p>
<p>Michael</p></div>friismtag:support.appharbor.com,2010-11-23:Comment/129555552012-01-18T23:56:49Z2012-01-18T23:56:49ZConnecting to Sequilizer with Code First Entity Framework.<div><p>Here are some tidbits of code that should help people in the
future (mocking the DbContext for the EntityFramework isn't
obvious):</p>
<p>Fake for IDbSet<br>
class ModelFakeDbSet : FakeDbSet where T : Model</p>
<pre>
<code>{
public override T Find(params object[] keyValues)
{
return this.SingleOrDefault(a => a.ID == (int)keyValues.Single());
}
}
// class mostly taken from http://romiller.com/2010/09/07/ef-ctp4-tips-tricks-testing-with-fake-dbcontext/
class FakeDbSet<T> : IDbSet<T> where T : class
{
protected HashSet<T> _data;
protected IQueryable _query;
public FakeDbSet()
{
_data = new HashSet<T>();
_query = _data.AsQueryable();
}
public virtual T Find(params object[] keyValues)
{
throw new NotImplementedException("Derive from FakeDbSet<T> and override Find");
}
public T Add(T entity)
{
_data.Add(entity);
return entity;
}
public T Attach(T entity)
{
return Add(entity);
}
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
{
throw new NotImplementedException("Not needed for tests");
}
public T Create()
{
throw new NotImplementedException("Not needed for tests");
}
public System.Collections.ObjectModel.ObservableCollection<T> Local
{
get { return new System.Collections.ObjectModel.ObservableCollection<T>(_data); }
}
public T Remove(T entity)
{
_data.Remove(entity);
return entity;
}
public IEnumerator<T> GetEnumerator()
{
return _data.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public Type ElementType
{
get { return _query.ElementType; }
}
public Expression Expression
{
get { return _query.Expression; }
}
public IQueryProvider Provider
{
get { return _query.Provider; }
}
}</code>
</pre>
<p>The base Model class<br>
public abstract class Model</p>
<pre>
<code>{
/// <summary>
/// The ID provided by the database.
/// </summary>
public int ID { get; set; }
}</code>
</pre>
<p>I'm using the Repository pattern to access the database, so I
abstracted the context away behind this interface:</p>
<p>///</p>
<pre>
<code>/// Repository interface for dealing with Account entities.
/// </summary>
public interface IAccountRepository : IDisposable
{
/// <summary>
/// Fetches all Account entities.
/// </summary>
/// <returns>All Account entities</returns>
IEnumerable<Account> GetAccounts();
/// <summary>
/// Searches for an Account entity with the numeric id provided
/// </summary>
/// <param name="id">The id of the desired Account</param>
/// <returns>The desired Account, if one exists, or null if no Account exists with that ID</returns>
Account GetAccountByID(int id);
/// <summary>
/// Searches for an Account with the id provided by the specified provider.
/// </summary>
/// <param name="id">The string id given by the provider</param>
/// <param name="provider">One of 'google', 'yahoo', 'myopenid', or 'openid'</param>
/// <returns>The desired Account, if one exists, or null if no Account exists with that ID</returns>
/// <exception cref="ArgumentNullException">If either id is null</exception>
/// <exception cref="AgrumentException">If provider is null or not one of the listed providers above</exception>
[NotNull]
Account GetAccountByID(String id, [ValueInSet("google", "yahoo", "myopenid", "openid")] String provider);
/// <summary>
/// Creates the account Account if it does not already exist (i.e. if the numeric ID is not 0 or could not be found in the database)
/// </summary>
/// <param name="account">The Accout object to be added to the database</param>
[NotNull]
void CreateAccount(Account account);
/// <summary>
/// Deletes the specified Account from the database, if it exists.
/// </summary>
/// <param name="account">The Account to be removed.</param>
[NotNull]
void DeleteAccount(Account account);
/// <summary>
/// Deletes the Account with the specified id, if it exists.
/// </summary>
/// <param name="id">The id of the Account to be removed.</param>
void DeleteAccount(int id);
/// <summary>
/// Marks the Account as updated.
/// </summary>
/// <param name="account">The Account to be updated.</param>
[NotNull]
void UpdateAccount(Account account);
/// <summary>
/// Saves all changes to the database.
/// </summary>
void Save();
}</code>
</pre>
<p>Ignore the annotations on that interface, they just do argument
checking for me (using the Interceptor pattern if you're curious).
To actually get tests to run, I mocked the DbContext as follows
(using the Moq library):</p>
<p>public class FakesAndMocksFactory</p>
<pre>
<code>{
public static ITrulySkilledContext CreateContext()
{
var accounts = new ModelFakeDbSet<Account>();
var mock = new Mock<ITrulySkilledContext>();
mock.Setup(obj => obj.Accounts).Returns(accounts);
mock.Setup(obj => obj.SaveChanges()).Returns(0);
mock.Setup(obj => obj.SetModified(It.IsAny<Model>()));
return mock.Object;
}
}</code>
</pre></div>nadreestag:support.appharbor.com,2010-11-23:Comment/129555552012-01-19T00:20:13Z2012-01-19T00:20:13ZConnecting to Sequilizer with Code First Entity Framework.<div><p>Thanks Nathen!</p></div>friism