Base solution for your next web application

Activities of "manifestarium"

You'll want to clean it up a bit I'm sure, but here's my working solution.

Install the "Auto T4" visual studio extension to trigger a regeneration when you build your solution, and never mess with updating your DbContext again!

<#@ template language="C#" debug="True" #> <#@ output extension="cs" #> <#@ assembly name="System" #> <#@ assembly name="System.Core" #> <#@ assembly name="System.ComponentModel.DataAnnotations" #> <#@ assembly name="System.Data" #> <#@ assembly name="$(SolutionDir)Trident.Core\bin\EntityFramework.dll" #> <#@ assembly name="Microsoft.CSharp" #> <#@ assembly name="$(SolutionDir)Trident.Core\bin\Abp.dll" #> <#@ assembly name="$(SolutionDir)Trident.Core\bin\Abp.Zero.dll" #> <#@ assembly name="$(SolutionDir)Trident.Core\bin\Trident.Core.dll" #> <#@ import namespace="System" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.ComponentModel.DataAnnotations.Schema" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Threading.Tasks" #> <#@ import namespace="Trident.Domain" #> <#

var coreAssembly = typeof(Trident.TridentCoreModule).Assembly;
var persistables = 
	coreAssembly.GetExportedTypes()
	.Where(ct =&gt; !ct.IsAbstract)
	.Where(ct => ct.GetCustomAttributes(typeof(TableAttribute), false).Any())
    .OrderBy(ct => ct.Name)
	.Select(ct => new { Type = ct, TableAttribute = (TableAttribute)ct.GetCustomAttributes(typeof(TableAttribute), false).First() })
	.ToArray();

#> using System; using System.Data.Entity; using System.Data.Entity.ModelConfiguration.Conventions; using System.Data.Common; using System.Data.Entity.Migrations.History; using System.Data.Entity.Infrastructure.Interception; using System.Data.Entity.SqlServer; using System.Data.SqlClient; using System.Diagnostics; using System.Reflection; using System.Linq; using Abp.Zero.EntityFramework; using Trident.Authorization.Roles; using Trident.MultiTenancy; using Trident.Users;

namespace Trident.EntityFramework { public partial class TridentDbContext : AbpZeroDbContext<Tenant, Role, User> {

<# var pluralizationService = new System.Data.Entity.Infrastructure.Pluralization.EnglishPluralizationService(); foreach(var p in persistables) { var propName = p.TableAttribute.Name ?? pluralizationService.Pluralize(p.Type.Name); WriteLine(" public virtual IDbSet<" + p.Type.FullName + "> " + propName + " { get; set; }"); } #>

	protected override void OnModelCreating(DbModelBuilder modelBuilder)
	{
	    base.OnModelCreating(modelBuilder);
		
		// Uncomment this if you want to use non-plural table names
	    //modelBuilder.Conventions.Remove&lt;PluralizingTableNameConvention&gt;();
		
		//modelBuilder.HasDefaultSchema(Trident.TridentConstants.SchemaName);
        //modelBuilder.ChangeAbpTablePrefix&lt;Tenant, Role, User&gt;("", Trident.TridentConstants.SchemaName);
		
    /* NOTE: 
     *   Setting "Default" to base class helps us when working migration commands on Package Manager Console.
     *   But it may cause problems when working Migrate.exe of EF. If you will apply migrations on command line, do not
     *   pass connection string name to base classes. ABP works either way.
	 *   Use the context's full namespace and name, if deploying to Azure, and make sure the connection string's name matches it.
     */
    public TridentDbContext()
        : base(typeof(TridentDbContext).FullName)
    {
	
    }

    /* NOTE:
     *   This constructor is used by ABP to pass connection string defined in TridentDataModule.PreInitialize.
     *   Notice that, actually you will not directly create an instance of TridentDbContext since ABP automatically handles it.
     */
    public TridentDbContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {
	
    }

    //This constructor is used in tests
    public TridentDbContext(DbConnection connection)
        : base(connection, true)
    {
	
    }
}

} <# #>

So for as long as I've used this framework, I've been baffled as to why I couldn't seem to get any of the samples or a fresh template solution to deploy to Azure and perform migrations. I solved the problem, but I continued thinking I was missing something and that others were doing this successfully.
After reading some forum posts on the subject, I think this just hasn't been confronted yet by the framework's developer. So, here's how you can get your solution to work like you expect on Azure: (Xyz = Name of your app)

  • In your Xyz.EntityFramework.XyzDbContext class > default constructor: DON'T pass "Default". Pass the full namespace and name of the context class. The publish wizard doesn't pick up on the DbContext unless you put it in the Web project directly, UNLESS your connection string in web.config has the same name as the DbContext. That's right, "Xyz.EntityFramework.XyzDbContext" needs to be your connection string name, and the value you pass to the default constructor. You may want to just backup and delete the publishing profile you're working with and create a new one after you make those changes, so it's configured correctly.
Showing 1 to 2 of 2 entries