0

Ok so here's some context: I'm using EF5, MVC4 and SQL CE4 to build up a web application. I've been loosely following this tutorial with a few differences.

  1. My context class and POCO objects are in their own assembly.
  2. I'm using SQL CE4 instead of SQL Express Local DB
  3. My classes aren't as simple as the tutorial

I've already used a workaround to get simple classes to work register.

I had thought using enums in EF5 was supported in EF5, but can they be used in Keys?

When I try to add a control (Add Controller, MVC controller with read/write actions and views, using Entity Framework) for a simple class (1 int key property, 1 string property), it works. I get varied errors when trying to add a class that has a property which is part of a key (primary or foreign)

Unable to retrieve metadata for 'blah'.  Using the 
same DbCompiledModel to create contexts against different types of 
database servers is not supported. Instead, create a separate 
DbCompiledModel for each type of server being used.

Index was out of range. Must be non-negative and less than the size of
the collection.
Parameter name: index

C:\Program Files (x86)\Microsoft Visual Studio\11.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC 4\
CodeTemplates\AddController\ControllerWithContext.tt(0,0) : error :
Running transformation: System.IndexOutOfRangeException: Index was outside the bounds of the
array.
---StackTrace---

The only similarities I've found between these classes is that they have an emun that's tied to a key. Other classes with non-key enums generate correctly. Is this the issue or have I completely missed the mark?

Edit: Example of a class which fails

public class A
{
    public virtual AIdEnum Id { get; set; }
    public virtual string Name { get; set; }

    public virtual ICollection<B> Bs { get; set; }
    public virtual ICollection<C> Cs { get; set; }
}
Community
  • 1
  • 1
Jake
  • 733
  • 8
  • 23
  • read this post http://amiramk.wordpress.com/2012/07/24/entity-framework-5-and-enum-support/ ... I think it will give you better insight into EF 5 enum key support. – Dave Alperovich Feb 08 '13 at 04:53
  • Can you provide any of your code for your POCO objects (not the whole thing). Also are you using code first, models first, db first? – Matt Whetton Feb 08 '13 at 13:18
  • @MattWhetton I've added an example. I'm also using code first. – Jake Feb 08 '13 at 15:13

3 Answers3

0

Ok, so I've just ran this up quickly with SQL CE 4 and it appears to work great:

public class EnumTestContext : DbContext
{
    public EnumTestContext() : base("CEDB")
    {

    }

    public DbSet<MyClass> MyClasses { get; set; }

}

public enum MyEnum
{
    EnumValue1,
    EnumValue2
}

public class MyClass
{
    [Key, Column(Order = 0)]
    public MyEnum MyEnumKey { get; set; }

    [Key, Column(Order = 1)]
    public int MyIntKey { get; set; }

    [Column(Order = 2)]
    public string Name { get; set; }

}

I then add an entity like this:

using (var context = new EnumTestContext())
{
    context.MyClasses.Add(new MyClass()
        {
        MyEnumKey = MyEnum.EnumValue1,
        MyIntKey = 22,
        Name = "Hello World"
        });
    context.SaveChanges();
}

This is all working fine for me - does this help?

Matt Whetton
  • 6,616
  • 5
  • 36
  • 57
  • Sadly it doesn't help. The issues I'm seeing are only with MVC4 code generation. I actually have a CLI interface for EF which hasn't had a problem with my code either. – Jake Feb 08 '13 at 16:07
0

You need put this line:

Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");

before the DbContext lifecicle beggin.

A exemple that you can to download in the MSDN Gallery

MayogaX
  • 469
  • 3
  • 18
  • Shouldn't defining that in the entityframework tag in web.config do the same thing? ie: ` ` – Jake Feb 08 '13 at 18:23
  • 1
    If you put that line in your ApplicationStrat() in your Global.asax it will work. Don't need change your connectionstring. Read about in my blog: [http://dev.mayogax.me/using-sqlserver-compact-edition-4-with-the-entity-framework](http://dev.mayogax.me/using-sqlserver-compact-edition-4-with-the-entity-framework) – MayogaX Feb 08 '13 at 18:36
  • That isn't changing the connection string but my connectionString does seem to be the issue. – Jake Feb 08 '13 at 18:57
  • This change in run time. The COnnectionFactory create the connectionString. Oh, or you are working with a existent db? – MayogaX Feb 08 '13 at 19:18
  • I meant to say that specifying the defaultConnectionFactory programmatically or through the config file worked the same way, but doesn't fix the issue. I had already updated my connection string to use SQLCE (which works, just not when trying to create controllers). I've posted my solution which might help clarify things more if I haven't explained them sufficiently yet. – Jake Feb 08 '13 at 20:01
0

It seems my issue is that Controller creation doesn't work with SQLCE 4.0 connectionStrings so using a conectionString of provider of System.Data.SqlClient handled that issue.

The next problem I had was that connectionString values (such as encryption) were not respected through this means so I now have 2 different constructors to get around this bug.

#if DEBUG
    public Context()
        : base("name=DefaultConnection")
    { ; }
#else
    /// <summary>
    /// Default Constructor
    /// </summary>
    public Context()
        : base("name=CompactConnection")
    { ; }
#endif

Here's my configuration:

<entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
        <parameters>
            <parameter value="System.Data.SqlServerCe.4.0" />
        </parameters>
    </defaultConnectionFactory>
</entityFramework>
<connectionStrings>
    <add name="CompactConnection" providerName="System.Data.SqlServerCe.4.0"
        connectionString="Data Source=&quot;|DataDirectory|\DB.sdf&quot;;encryption mode=platform default;password=&quot;P4$$w0rd!&quot;"/>
    <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MsSqlCe-20121028004432;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-MsSqlCe-20121028004432.mdf" />
</connectionStrings>

Of course, this is just a workaround for a deeper issue. If anyone else knows of the root cause of this issue, I'd love to know.

Jake
  • 733
  • 8
  • 23