Giter Site home page Giter Site logo

dotnet / ef6 Goto Github PK

View Code? Open in Web Editor NEW
1.4K 154.0 534.0 47.09 MB

This is the codebase for Entity Framework 6 (previously maintained at https://entityframework.codeplex.com). Entity Framework Core is maintained at https://github.com/dotnet/efcore.

Home Page: https://docs.microsoft.com/ef/ef6

License: MIT License

Batchfile 0.02% C# 98.37% Yacc 0.18% Lex 0.01% PowerShell 0.73% Shell 0.38% CMake 0.05% TSQL 0.01% Visual Basic .NET 0.27%
entity-framework dotnet-framework orm database ef6 entity-framework-6

ef6's Introduction

Entity Framework 6

Entity Framework 6 (EF6) is an object-relational mapper that enables .NET Framework, .NET Core, and modern .NET developers to work with relational data using domain-specific objects. It eliminates the need for most of the data-access code that developers usually need to write.

Status and Support

The latest version of EF6 is still supported by Microsoft--see Entity Framework Support Policies for details. However, EF6 is no longer being actively developed. This means that:

  • Security issues will be fixed, as for any supported product.
  • High-impact bugs, typically those impacting a very large number of users, may be fixed.
  • Other bugs will not be fixed.
  • New features will not be implemented

This plan focuses on stability of the codebase and compatibility of new versions above all else, excepting security. In general, the EF6 codebase is reliable and has been stable for several years with few significant bugs. However, due to the complexity and number of usage scenarios, and also the sheer number of applications that use EF6, any change has the potential to regress existing behaviors. This is why we will be making only security fixes. Also, we will not be accepting pull requests made by the community, again to ensure stability of the codebase.

Entity Framework Core

Entity Framework Core (EF Core) is a lightweight and extensible version of Entity Framework and continues to be actively developed on the EFCore GitHub repo. EF Core is developed exclusively for modern .NET and does not run on .NET Framework. EF Core includes many improvements and new features over EF6. EF Core has a different architecture to EF6 and takes a very different approach to its internals--for example, EF Core does not support a visual designer or EDMX files. However, most EF6 projects can be ported to EF Core with some amount of work--see Port from EF6 to EF Core for a guide.

Forks

The EF6 code is published under the MIT. This means it is permissible to fork the code and build custom versions of EF6. Making changes in a fork is one way to work around any issues or add new features without impacting the stability of the main branch and releases. Indeed, there are commercial third-party forks of EF6 available for a fee that add new features to EF6. (Microsoft does not endorse or provide support for any forked versions of EF6.)

Note that a fork is not needed to use EF6 on .NET Core and modern .NET platforms; the existing EF6 packages already support this.

Getting help

See the EF6 docs for installation, documentation, tutorials, samples, etc. This documentation is no longer being updated, but still contains useful and usable content.

The EF team is focusing efforts on EF Core, and hence team members are unlikely to respond to issues filed on this repo. We recommend asking questions on Stack Overflow.

You may instead choose to contact a Microsoft Support professional for support. Please note that this may incur a fee.

EF6 Tools for Visual Studio

The code for the EF6 Tools for VS (including the visual designer) can be found in the EF6Tools repo.

EF6 PowerTools

The EF6 PowerTools is a community-driven project with its own GitHub repo.

ef6's People

Contributors

ajcvickers avatar andriysvyryd avatar anpete avatar backs avatar brandondahler avatar bricelam avatar chrfin avatar davidobando avatar divega avatar dotnet-bot avatar dotnet-maestro[bot] avatar dougbu avatar erikej avatar glennc avatar idisposable avatar jkotalik avatar lajones avatar leotsarev avatar lukewaters avatar martincostello avatar maumar avatar mlacouture avatar mmitche avatar montanehamilton avatar nschonni avatar rogeralsing avatar rowanmiller avatar smudge avatar unaizorrilla avatar wtgodbe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ef6's Issues

EF 6 CodeFirst Migrations Detecting changes that don't exist

I have been using EF Migrations for a while in my current project and all was working great, that is until today, the situation is as follows:

  1. I made a small change of adding a string property
  2. I called an API method and got an error that there are changes in the model
  3. I ran the command "Add-Migration MigrationXYZ"
  4. A new migration is created with extra changes that didn't happen

I ran the "Add-Migration MigrationXYZ -Force" to make sure its not a one thing issue, I dropped the DB, restarted VS(2015) but all the same

Another issue is that even if I apply the migration as done by the scaffolder, an error still returns saying "Unable to update database to match the current model because there are pending changes..."

After looking at these changes, they all but one are about having a string property with the [Required] attribute and the scaffolder need to make it nullable, below is a sample.

public partial class MigrationXYZ: DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.Foos", "NewProperty", c => c.String());//<-- Expected Change
        AlterColumn("dbo.Bars", "Name", c => c.String());//<-- Unexpected Change
    }

    public override void Down()
    {
        AlterColumn("dbo.Bars", "Name", c => c.String(nullable: false));//<-- Unexpected Change
        DropColumn("dbo.Foos", "NewProperty");//<-- Expected Change
    }
}

public class Bar
{
    //This was not touched in ages, some even before adding the first migration
    [Required]
    public string Name { get; set; }
}

And now I am stuck and don't know how to fix this...Corruption in the Migration state

Edit

I have been trying to debug the Add-Migration command to understand why does EF see the model is different than it really is, but using EF source is not possible when you have dependencies like Identity which needs signed DLLs to work.

However additional research lead me to the answer here which leads to this blog post By @trailmax and the code to decipher the migrations hash, and with a little search in the EF source I made a small app to extract both the current model and the last migration model to compare side to side.

The code to get the current model representation in XML

//Extracted from EF Source Code
public static class DbContextExtensions
{
    public static XDocument GetModel(this DbContext context)
    {
        return GetModel(w => EdmxWriter.WriteEdmx(context, w));
    }

    public static XDocument GetModel(Action<XmlWriter> writeXml)
    {
        using (var memoryStream = new MemoryStream())
        {
            using (var xmlWriter = XmlWriter.Create(
                memoryStream, new XmlWriterSettings
                {
                    Indent = true
                }))
            {
                writeXml(xmlWriter);
            }

            memoryStream.Position = 0;

            return XDocument.Load(memoryStream);
        }
    }
}

        //In Program.cs
        using (var db = new DbContext())
        {
            var model = db.GetModel();
            using (var streamWriter = new StreamWriter(@"D:\Current.xml"))
            {
                streamWriter.Write(model);
            }
        }

The code to extract the model from the migration in XML

//Code from Trailmax Tech Blog
public class MigrationDecompressor
{
    public string ConnectionString { get; set; }

    public String DecompressMigrationFromSource(IMigrationMetadata migration)
    {
        var target = migration.Target;
        var xmlDoc = Decompress(Convert.FromBase64String(target));
        return xmlDoc.ToString();
    }

    public String DecompressDatabaseMigration(String migrationName)
    {
        var sqlToExecute = String.Format("select model from __MigrationHistory where migrationId like '%{0}'", migrationName);

        using (var connection = new SqlConnection(ConnectionString))
        {
            connection.Open();

            var command = new SqlCommand(sqlToExecute, connection);

            var reader = command.ExecuteReader();
            if (!reader.HasRows)
            {
                throw new Exception("Now Rows to display. Probably migration name is incorrect");
            }

            while (reader.Read())
            {
                var model = (byte[])reader["model"];
                var decompressed = Decompress(model);
                return decompressed.ToString();
            }
        }

        throw new Exception("Something went wrong. You should not get here");
    }

    /// <summary>
    /// Stealing decomposer from EF itself:
    /// http://entityframework.codeplex.com/SourceControl/latest#src/EntityFramework/Migrations/Edm/ModelCompressor.cs
    /// </summary>
    private XDocument Decompress(byte[] bytes)
    {
        using (var memoryStream = new MemoryStream(bytes))
        {
            using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
            {
                return XDocument.Load(gzipStream);
            }
        }
    }
}

        //Inside Program.cs

        var decompresser = new MigrationDecompressor
        {
            ConnectionString = "<connection string>"
        };

        var databaseSchemaRecord = decompresser.DecompressDatabaseMigration("<migration name>");
        using (var streamWriter = new StreamWriter(@"D:\LastMigration.xml"))
        {
            streamWriter.Write(databaseSchemaRecord);
        }

Unfortunately I still cannot find the issue, the only difference between the model and the one hashed with the last migration is the expected change of the added property, none of the unexpected changes show up, also after running the migration suggested by EF, then comparing the current model with the suggested migration, still the model doesn't match the changes, what should be not null is still not null in the model, while the suggested migration show it as nullable.

The expected changes show up

<Property Name="NewProperty" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" />
.
.
.
<ScalarProperty Name="NewProperty" ColumnName="NewProperty" />
.
.
.
<Property Name="NewProperty" Type="nvarchar(max)" Nullable="true" />

Note: this was also posted on stackoverflow

AddOrUpdate error when identifyingProperty is nullable

Hi,

There is an error in AddOrUpdate method. Let's look on such example:

public class Test
{
    public Guid? SomeKey { get; set;}
}

protected override void Seed(TestContext context)
{
        var entity = new Test() { SomeKey = Guid.NewGuid()};
        context.Tests.AddOrUpdate(t => t.SomeKey, entity); 
}

Running such code creates error:

The binary operator Equal is not defined for the types 'System.Nullable`1[System.Guid]' and 'System.Guid'.

Problem lays in invalid condition createion based on identifier parameter in AddOrUpdate method:

Expression.Equal(
                            Expression.Property(parameter, pi.Single()),
                            Expression.Constant(pi.Last().GetValue(entity, null)))

Expression.Property returns expression of type Guid?. Expression.Constant return expression of type Guid. And Equals cannot join it.

The solution is to add parameter to Expression.Constant about type of property.

                            Expression.Constant(pi.Last().GetValue(entity, null), pi.Last().PropertyType))

Then it will cast this expression to be Guid? and it will run property.

I think that this will also occure on EF7. but i didn't use it already.

Database.CommandTimout not applied consistently

The value set on Database.CommandTimout is not configured on various DbCommands created on behalf of a DbContext to execute database initialization operations and to retrieve serverproperty('EngineEdition') on SQL Server.

From the symptoms described at http://stackoverflow.com/questions/38317660/azure-webjob-timeout-when-calling-stored-procedure/38359399 and some internal threads it seems that this can have customer impact, especially when using Azure SQL Database.

Note that DbMigrationsConfiguration has its own CommandTimeout property that should be applied to migration operations.

Workaround

It is possible to use command interception to set the timeout, e.g.:

using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure.Interception;

namespace CommandTimeOutBug
{
    class Program
    {
        static void Main(string[] args)
        {
            DbInterception.Add(new MyInterceptor());

            using (var context = new ApplicationDbContext())
            {

                context.Database.CommandTimeout = 2;

                context.PopulateJobTypeDescendants();
            }
        }
    }

    public class ApplicationDbContext : DbContext
    {

        public void PopulateJobTypeDescendants()
        {
           Database.ExecuteSqlCommand("PopulateJobTypeDescendants");
        }
    }

    public class MyInterceptor: DbCommandInterceptor
    {

        public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            command.CommandTimeout = 2;
            base.NonQueryExecuting(command, interceptionContext);
        }

        public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            command.CommandTimeout = 2;
            base.ReaderExecuting(command, interceptionContext);
        }

        public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            command.CommandTimeout = 2;
            base.ScalarExecuting(command, interceptionContext);
        }
    }
}

Null Reference Exception generating views using Power Tools

When using Visual Studio 2012 with Update 5 and EF 6.1.3 and the EF 6 Power Tools, when I click on
Entity Framework > Generate Views, I get a NullReferenceException in Microsoft.DbcontextPackage.Handlers.OptimizeContextHandler.OptimizeEmdx

The NullReferenceException was the result of the type resolution service not being able to resolve the EF6 assembly (ef6Assembly == null).

ByteBuilder wrote Dec 8, 2015 at 1:53 PM [x]

The proposed fix is to OptimizeContextHandler.cs in the PowerTools project is (from line 106):

                var typeService = _package.GetService<DynamicTypeService>();
                var solution = _package.GetService<SVsSolution, IVsSolution>();
                IVsHierarchy hierarchy;
                solution.GetProjectOfUniqueName(project.UniqueName, out hierarchy);
                var typeResolutionService = typeService.GetTypeResolutionService(hierarchy);
                var ef6Assembly = typeResolutionService.GetAssembly(
                    new AssemblyName { Name = ef6Reference.Name, Version = new Version(ef6Reference.Version) });

                    if (ef6Assembly != null)
                    {
                        string containerName;
                        var mappingCollection = edmxUtility.GetMappingCollectionEF6(ef6Assembly, out containerName);
                        var contextTypeName = selectedItem.ProjectItem.GetDefaultNamespace() + "." + containerName;

                        OptimizeContextEF6(languageOption, baseFileName, mappingCollection, selectedItem, contextTypeName);
                    }
                    else
                    {
                        var mappingCollection = edmxUtility.GetMappingCollection();

                        OptimizeContextEF5(languageOption, baseFileName, mappingCollection, selectedItem);
                    }

RoMiller wrote Feb 22 at 11:42 AM [x]

Note for Triage: In our last triage we couldn't remember if we had APIs in EF6 for this - we do https://msdn.microsoft.com/en-us/data/dn469601#code.

Entity Framework 6 - Second level Caching Alias name

Hi,

I am using Entity Framework 6 and using second level of caching of entities to improve performance.

One of the problems we are facing is with the Alias names in the query.

On a high load scenario, the alias name generated for a query are different which is resulting in both the queries being treated as different and it breaks the caching.

For Eg:
SELECT Var_251.id from user Var_251 where <>

The same query for the user on a high load is getting generated as
SELECT Var_252.id from user var_252 where <>

since both the queries are different, the hash of the query which is used as a key to store the result set becomes different. So data cached in the first query is not reusable in second query by the same user.

IF we run the application with a single user the query alias name generated is always same, but the moment to move say 5+ user load, the query being generated gets different.

So just wanted to confirm if there is a way to override this default behaviour so that it uses the same alias everytime for the query or if this is a known issue in the EF 6.

Error after adding ADO.NET Entity Data Model in VS 2017

I have a winform app and it does build successfully. Then I tried to add a ADO.NET Entity Data Model into my project which connects to sqlcldb4 RS_NorthWind database, and after that I tried to rebuild it, it threw me some errors (refer to picture attached).
I just tried the scenario in another machine and it still reproes. So I believe the failure is common. I installed from the following path \cpvsbuild\drops\VS\preview\layouts\x86ret\25107.00\enu\vs\enterprise\dvd, and the repro step is pretty simple:

  1. Create a WinForm application
  2. Add a new item “ADO.NET Entity Data Model”
  3. Choose “EF Designer from database”
  4. Click “New Connection…”, add RS_Northwind database from sqlcldb4 using Windows Authentication
  5. Only choose “Customers” table, and click “Finish”
  6. It will pop up some security warnings saying “Running this text template can potentially harm your computer. Do not run it if you obtained it from an untrusted source.”, and hit “OK”
  7. Then in the Error List window, there are already several errors shown up.
  8. If you rebuild the project, it will give the errors that we see in the picture.

SqlCommand.Parameters having same variable declared twice

Hi,

I am working in some interceptor for multi-tenant application and when I was doing INSERT behavior, I found something strange.
Here is my code that change DbInsertCommandTree:

public class DbInsertCommandTreeHandler : CommandTreeHandlerBase
{
    private const string COLUMN_NAME = "TenantId";

    protected override bool CanHandle(DbCommandTree command)
    {
        return command is DbInsertCommandTree;
    }

    protected override DbCommandTree Handle(DbCommandTree command)
    {
        var insertCommandTree = command as DbInsertCommandTree;

        var dbSetClauses = insertCommandTree.SetClauses.Cast<DbSetClause>().ToList();

        var setClause = dbSetClauses.FirstOrDefault(HasColumn);
        if (setClause != null)
        {
            dbSetClauses.RemoveAll(HasColumn);
            dbSetClauses.Add(CreateSetClause(setClause));

            return new DbInsertCommandTree(insertCommandTree.MetadataWorkspace,
                insertCommandTree.DataSpace,
                insertCommandTree.Target,
                dbSetClauses.Cast<DbModificationClause>().ToList().AsReadOnly(),
                insertCommandTree.Returning);
        }
        return insertCommandTree;
    }

    private static DbSetClause CreateSetClause(DbSetClause expression)
    {
        var propertyExpression = expression.Property as DbPropertyExpression;
        return DbExpressionBuilder.SetClause(propertyExpression, propertyExpression.ResultType.Parameter("tenantId"));
    }

    private static bool HasColumn(DbSetClause setClause)
    {
        return (setClause.Property as DbPropertyExpression).Property.Name == COLUMN_NAME;
    }
}

When testing my code in test app, I received this exception:

The variable name '@tenantId' has already been declared. Variable names must be unique within a query batch or stored procedure.

So I added a breackpoint in my custom IDbCommandInterceptor in ReaderExecuting method. Then I saw that DbCommand had 10 parameters, first one was tenantId and last one @TenantID, I digged in my code to check were the first parameter came from. I didn't found it. The command tree generated from my DbInsertCommandTreeHandler produced this:

DbInsertCommandTree
|_Parameters
| |_tenantId : Edm.Int64
|_Target : 'target'
| |_Scan : CodeFirstDatabase.Contato
|_SetClauses
| |_DbSetClause
| | |_Property
| | | |_Var(target).Nome
| | |_Value
| |   |_'Alberto'
| |_DbSetClause
| | |_Property
| | | |_Var(target).Endereço_Rua
| | |_Value
| |   |_'Avenida F'
| |_DbSetClause
| | |_Property
| | | |_Var(target).Endereço_Bairro
| | |_Value
| |   |_'Benfica'
| |_DbSetClause
| | |_Property
| | | |_Var(target).Endereço_Complemento
| | |_Value
| |   |_null
| |_DbSetClause
| | |_Property
| | | |_Var(target).Endereço_Numero
| | |_Value
| |   |_1
| |_DbSetClause
| | |_Property
| | | |_Var(target).Endereço_Cep
| | |_Value
| |   |_0
| |_DbSetClause
| | |_Property
| | | |_Var(target).Telefone
| | |_Value
| |   |_'30211083'
| |_DbSetClause
| | |_Property
| | | |_Var(target).Celular
| | |_Value
| |   |_'86234779'
| |_DbSetClause
| | |_Property
| | | |_Var(target).Inativo
| | |_Value
| |   |_False
| |_DbSetClause
|   |_Property
|   | |_Var(target).TenantId
|   |_Value
|     |_@tenantId
|_Returning
  |_NewInstance : Record['Id'=Edm.Int64]
    |_Column : 'Id'
      |_Var(target).Id

So, I cloned EF repository and started to debug EF source code, and I realized that EF were adding the parameter tenantId twice.

In System.Data.Entity.SqlServer.SqlGen.DmlSqlGenerator at lines 248 ~ 267 EF create parameters from the SetClauses.

When code flow reach in System.Data.Entity.SqlServer.SqlProviderServices at lines 257 ~ 286 EF create SqlParameters from command tree parameters(commandTree.Parameters) and then add to SqlCommand.Parameters.

After that in lines 289 ~ 302 EF get parameters generated from DmlSqlGenerator and then add to SqlCommand.Parameters.

And then the SqlCommand.Parameters have parameter tenantId duplicated. One from commandTree.Parameters and another from commandTree.SetClauses.

I that behavior normal?

OData+EF on inherited back-navigations

This is the same issue reported here: https://entityframework.codeplex.com/workitem/2903
and cross-posted here: OData/odata.net#679

We have troubles using OData queries on a service based on EntityFramework.
The problem arises when we try to expand inherited back-navigation properties.
In attachment you can find a minimal example which reproduces the problem.

We have entities in the following hierarchy:
Base-->Derived-->DerivedDerived-->DerivedDerivedDerived
A back-navigation is declared on "Base" and queried on all four entity-types just to find that it only works on "Base" and "DerivedDerivedDerived" (i.e. only the least and most extended types).

The queries we tried are:
[...]/odata/Base?$expand=BackNav
[...]/odata/Derived?$expand=BackNav
[...]/odata/DerivedDerived?$expand=BackNav
[...]/odata/DerivedDerivedDerived?$expand=BackNav

Only cases 1 and 4 are working.

Cases 2 and 3 throw exception:
{ "error":{ "code":"","message":"An error has occurred.","innererror":{ "message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata.metadata=minimal'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{ "message":"An error occurred while preparing the command definition. See the inner exception for details.","type":"System.Data.Entity.Core.EntityCommandCompilationException","stacktrace":" at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)\r\n at ...

OdataTest.zip

IndexAttribute or IndexAnnotation not working while initializing MySQL

I haven't tested with SQL Server yet and am not sure if the issue is only for MySQL.

Package versions:

  • EntityFramework 6.1.3
  • MySql.Data 6.9.9
  • MySql.Data.Entity 6.9.9

Simplified code:

public class MyDbContext : DbContext
{
    public MyDbContext() : base("MyDbContextConnectionString")
    {
        Database.SetInitializer(new MyDbInitializer());
    }

    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // The following code doesn't work either.
        // modelBuilder.Entity<User>()
        //     .Property(e => e.Mobile)
        //     .HasColumnAnnotation(
        //         IndexAnnotation.AnnotationName,
        //         new IndexAnnotation(new IndexAttribute("IX_Mob") { IsUnique = true }));
    }
}

public class MyDbInitializer : DropCreateDatabaseAlways<MyDbContext>
{
}

public class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    [Index(IsUnique = true)]
    public string Mobile { get; set; }
}

internal static void Main(string[] args)
{
    using (var context = new MyDbContext())
    {
        // ...
    }
}

I expect the table to be created with a primary key Id and a unique index for column Mobile. But the result was that a primary key index for Id was created, and a redundant unique index for Id was also created, but the expected unique index for Mobile was not.

Screenshots from MySQL Workbench:

s1

s2

Full code and project files:

eftest.zip

Creating a model from an existing database takes a few minutes with recent versions of SQL Server

This was originally reported by @julielerman at microsoft/sql-server-samples#57 while trying the OLTP version of the new SQL Server 2016 sample databases, WorldWideImporters (https://github.com/Microsoft/sql-server-samples/releases/tag/wide-world-importers-v1.0).

I have created this issue on our side to follow up with the SQL Server team.

Repro steps:

  1. Create new class library project.
  2. Add new item: Entity Framework Data Model.
  3. Select connection to World Wide Importers (not DW) on SQL Server 2016 instance.
  4. Select all tables.
  5. Go (which will install EF6 package and reverse engineer tables into classes).

Observed result:
It takes about 3 minutes.

Expected result:
It should take about 10 seconds max.

Cause:
What we know so far is that this is a regression caused by differences in SQL Server 2016's cardinality estimator (CE). There have been similar issues in SQL Server 2014, which we tried to workaround by introducing OPTION (QUERYTRACEON 9481) on our reverse engineering queries but that didn't work for customers that didn't have enough permissions to use QUERYTRACEON.

Workaround:
It should be possible to temporarily downgrade the cardinality estimator on a specific database to use previous behaviors:

  1. Execute ALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION=ON on the database
  2. Perform reverse engineering using the EF Wizard
  3. Execute ALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION=OFF on the database

Follow up actions:
We are in contact with the SQL Server team regarding this issue and the follow up action is to work with them to see if the CE can be tweaked to eliminate the regression or if there is anything we can do on the EF side.

cc @jodebrui

Add-Migration fails to configure composite-key indexes properly

Steps To Reproduce:

  1. Load Solution in VS2015
  2. In Package Manager Console, execute the command:
    PM> Add-Migration Initial

Expected Results:
In the newly created migration file, the first index, "ix1" should have a composite key (LogFileID + SubTItleMessageId) as coded on lines 14-17 in LogRecordConfig.cs

Observed Results:

  1. In the migration file, note that on line 21, the index named "ix1" has a single-property key. The LogFileID portion of the key is missing.
  2. If the order of the index declaration in LogRecordConfig.cs is reversed, the problem seems to always occur on the first index declared (i.e. The second index created in the migration file)

AddMigrationBug.zip

6.1.3 Inheritance Bug (6.1.1 works fine)

With this model

public class Class1
{
    [Key]
    public int Id { get; set; }

    public virtual string MyProperty { get; set; }
    // other properties 
}

public class Class3 : Class1
{
    [Required]
    public override string MyProperty { get; set; }

    public string Class3Prop { get; set; }
}


public class TestContext : DbContext
{
    public TestContext(DbConnection connection) : base(connection, true) { }

    public DbSet<Class1> C1s { get; set; }
    public DbSet<Class3> C3s { get; set; }


}

I expect that Class3.MyProperty is required and Class1.MyProperty is not required.

With EF 6.1.1 everything's working fine (in SQL Server the MyProperty field is nullable).
With EF 6.1.3 both Class3.MyProperty and Class1.MyProperty are interpreted as Required (and in SQL Server MyProperty field is not nullable)

primary key naming convention

Is there a way to insert a PK naming convention since the default gives issues when the tablename is prefixed with the tablespace name e.g. dbo.SomeTableName.

I use MS Access as a frontend during development (just because it's easy to validate data and set up lookup columns.)

This gives errors due to the fact that the dbo part is also used as PK namig convention. Why not replace this kind of "special" characters by something else like underscore. This should make everybody happy. or atleast make this type of crucial functions virtual for user extensibility.

Migration commands fail for projects in a visual studio solution folder

Migration commands fail for projects in a visual studio solution folder

Functional impact

Migrations stop working as long as the project remains in the solution folder. The workaround of moving the project into the solution root, doing the migration and moving it back into the solution folder works, but isn't that obvious.

Minimal repro steps

  1. Create a project
  2. Add nuget package for EF latest stable (6.1.3)
  3. Enable migrations
  4. Create a solution folder
  5. Move the project into the solution folder
  6. Try to add a migration

Expected result

Migration is added

Actual result

Command fails with the message The EntityFramework package is not installed on project ''.

All paths of ConditionalExpression are evaluated

When a ConditionalExpression depends on only client variables, I would expect the entire ConditionalExpression to be evaluated in the Funcletizer process. Instead, only the child expressions are evaluated. This can cause issues with ConditionalExpressions used to check for null.

In this example, if the equipment is null, the conditional should evaluate to false. When executing it, I get an error "Non-static field requires a target."

Equipment equipment = null;
Expression<Func<Equipment, bool>> expr = (eq) => Equipments.Any(a => (eq != null ? eq.ObjectID : Guid.Empty) != Guid.Empty);
expr.Compile().Invoke(equipment);

Modifying the last line of IsClosureExpression to the following makes this query run properly.
return ExpressionType.Conditional == expression.NodeType;

Db Migration Fails when trying to update.

From @rufio620 on August 20, 2016 3:13

Steps to reproduce

I added a new table to my database which participates in a one to many relationship with another table. When I scaffold the migration I get the following code.

public override void Up()
        {
            CreateTable(
                "TemplateDefinition",
                c => new
                    {
                        Id = c.Guid(nullable: false),
                        BusinessDomainId = c.Guid(nullable: false),
                        InputViewModelId = c.Guid(),
                        SystemName = c.String(nullable: false, maxLength: 255),
                        TemplateMarkup = c.String(),
                        InvariantId = c.Guid(nullable: false),
                        DisplayName = c.String(nullable: false, maxLength: 255),
                        Description = c.String(),
                    })
                .PrimaryKey(t => t.Id)
                .ForeignKey("BusinessDomainDefinition", t => t.BusinessDomainId, cascadeDelete: true)
                .ForeignKey("ViewModelDefinition", t => t.InputViewModelId)
                .Index(t => t.BusinessDomainId)
                .Index(t => t.InputViewModelId);

        }

Upon applying this migration I get the following error.

Applying explicit migrations: [201608200256366_MigTemplateDefs].
Applying explicit migration: 201608200256366_MigTemplateDefs.
The Foreign Key on table 'TemplateDefinition' with columns 'InputViewModelId' could not be created because the principal key columns could not be determined. Use the AddForeignKey fluent API to fully specify the Foreign Key.

The BusinessDomainDefinition table was created in a previous migration and has a primary key. There are also several other 1 to many child tables created in the initial migration that are applied without the same error.

The issue

EF Migrations should be able to apply this without an issue. It is a simple 1 to many relationship. If I delete all migrations and re scaffold the entire database the update works without any problem.

If you are seeing an exception, include the full exceptions details (message and stack trace).

Exception message:
Stack trace:

Further technical details

EF Version 6.1.3
Visual Studio 2015 Community

Other details about my project setup:

Copied from original issue: dotnet/efcore#6378

Inconsistent behavior for related entities in AddOrUpdate depending on whether root entity is new or existing

Working with a common many-to-many scenario, code first, EF 6.02.

Product >-< Category

I have a context with MigrateDatabaseToLatestVersion initializer. In the configurations's Seed method I add a few products and categories and establish the many to many by adding products to Category.Products.

The essential code (where db is a DbContext):

db.Products.AddOrUpdate(x => x.Name, p1, p2, p3, p4, p5, p6); // p1 etc. are products
var shoes = db.Categories.Create();
// set properties

shoes.Products.Add(p1);
shoes.Products.Add(p4);
shoes.Products.Add(p6);

// More categories

db.Categories.AddOrUpdate(x => x.CategoryName, sports, accessories, shoes);

When the database is created everything is fine.

With an existing database I try to add a new product in an existing category. This code runs after the code above, before the SaveChanges call.

var p7 = db.Products.Create();
db.Products.AddOrUpdate(x => x.Name, p7);
shoes.Products.Add(p7)

The result is that the new product is saved, but not the many to many association. This is because at this point, shoes is in a Detached state, so the change tracker doesn't notice the addition.

Now if instead of shoes.Products.Add I do

p7.Categories.Add(shoes);

the association is saved, but all existing products in shoes are duplicated. I understand that this is because shoes, and all its products, are marked as Added.

If I do

db.Entry(shoes).State = EntityState.Unchanged;

I get a duplicate key exception, which I don't understand, because shoes is Detached.

The only way I'm aware of to get this working is

shoes = db.Categories.Single(c => c.CategoryName == shoes.CategoryName);
shoes.Products.Add(p7);

So, finally, my question. You guys probably have good reasons not to attach existing entities in an AddOrUpdate call. However, the above scenario would become much more transparent and intuitive if it did attach existing entities.

It's probably a big issue to change this behavior, but could it be an optional feature of AddOrUpdate, as a third parameter attachExisting?

Migrate.exe runs all the migrations even if they are already applied

It looks like migrate.exe is not interpreting right the exceptions - for example if user, that is used to connect to database when running migrate.exe does not have rights to read migration history table (is only ddladmin), migrate.exe tries to run all the migrations, instead of showing error for missing permissions.

It took lots of time and reverse engineering to figure this out.

Replace %VSnnnCOMNTOOLS% with $(DevEnvDir) in T4 templates

In 013d453 I checked in a change to insert $(DevEnvDir) into the Dev15 version of various T4 template files, rather than the previous reference to %VS150COMNTOOLS%. This was because %VS150COMNTOOLS% no longer exists under the low-impact install.

This bug is to consider replacing %VS150COMNTOOLS% with $(DevEnvDir) for the builds for Devs 11, 12 & 14 as well.

AddOrUpdate generate query with inlined parameter

AddOrUpdate make query to check if entity already exists in db
query look like:

SELECT TOP (2) 
    [Extent1].[Id] AS [Id], 
    ... other fields ...
    FROM [Table] AS [Extent1]
    WHERE N'id-value' = [Extent1].[Id]

I expecte query to look like:

SELECT TOP (2) 
    [Extent1].[Id] AS [Id], 
    ... other fields ...
    FROM [Table] AS [Extent1]
    WHERE @p__linq__0 = [Extent1].[Id]

Verify EF packages work correctly in Visual Studio 2017

We have been made aware of various compatibility issues at various stages of the development of Visual Studio 15. In particular issues around components no longer being in the GAC in low-impact installs and implicit dependencies and other assumptions in our PowerShell scripts and our treatment of AppDomains.

Many known issues have been fixed but we should keep testing our packages with recent builds.

Improve Debugability of EntityFramework for Developers by providing more precise / meaningful errors (Entity Names along with the PropertyName)

Hello
Again, I had to search for several days for the root cause of an illegal state within my entity set, just because of an imprecise error message. Even worse, there is no way to download the pdb files (as far as i could discover).

Finally I was able to find the root cause by building EF for myself, to be able to debug into it.

For example:

throw new InvalidOperationException(Strings.ObjectStateEntry_CannotModifyKeyProperty(memberName));
would be much more meaningful written as:

throw new InvalidOperationException(Strings.ObjectStateEntry_CannotModifyKeyProperty(entityName, memberName));

Stop depending on NuGet.VisualStudio.IVsPackageInstallerServices for PMC commands

Currently we depend on resolving an instance of the interface NuGet.VisualStudio.IVsPackageInstallerServices to lockage the NuGet package installation path.

This has proved to be very brittle. We have been broken a couple of times already, e.g. lately by a change in the behavior of PowerShell: https://entityframework.codeplex.com/workitem/2872.

@BriceLambson has a few ideas to replace this logic. Creating this work item to track this for a future improvement.

ExecuteStoreQueryAsync fails with System.ArgumentException

From @micktion on September 9, 2016 8:23

I'm not sure if you're taking 6.1.3 issues or if this is an issue in EF 7. I'll detail what I found as per your template...

Steps to reproduce

Pass MergeOption in place of ExecutionOptions

The issue

Fails with System.ArgumentException: No mapping exists from object type System.Data.IDataParameter[] to a known managed provider native type.

Exception message: System.ArgumentException: No mapping exists from object type System.Data.IDataParameter[] to a known managed provider native type.

Stack trace:
at System.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__167_0(Task`1 result)
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Core.Objects.ObjectContext.<ExecuteStoreQueryInternalAsync>d__6f`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Utilities.TaskExtensions.CultureAwaiter`1.GetResult()
   at System.Data.Entity.Core.Objects.ObjectContext.<ExecuteInTransactionAsync>d__3d`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<ExecuteAsyncImplementation>d__9`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Utilities.TaskExtensions.CultureAwaiter`1.GetResult()
   at System.Data.Entity.Core.Objects.ObjectContext.<ExecuteStoreQueryReliablyAsync>d__6c`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Tonic.Oms.Api.Tests.CoreTests.<TestStoreQueryAsync>d__25.MoveNext() in E:\Projects\oms-platform\Tonic.Oms.Api\Tonic.Oms.Api.Tests\CoreTests.cs:line 432
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()

Further technical details

The code that reproduces this issue is...

IDataParameter[] parameters = new IDataParameter[] {
    repository.CreateStoreQueryParameter("@LogonId", logonId),
    repository.CreateStoreQueryParameter("@Password", password),
    repository.CreateStoreQueryParameter("@status", status)};

var list = await repository.ModelObjectContext.ExecuteStoreQueryAsync<UserPasswordEntity>(
            commandText,
            MergeOption.AppendOnly,
            parameters);

Now it took me an afternoon to notice as this code compiles, runs then fails with a run time error, but the 2nd parameter should actually be of type ExecutionOptions and not a MergeOption enum. I don't know how this compiles, but it does, I'm guessing somewhere out there is an explicit cast operator from MergeOption to ExecutionOptions.

So when you pass ExecutionOptions it executes successfully...

ExecutionOptions options = new ExecutionOptions(MergeOption.AppendOnly);

IDataParameter[] parameters = new IDataParameter[] {
    repository.CreateStoreQueryParameter("@LogonId", logonId),
    repository.CreateStoreQueryParameter("@Password", password),
    repository.CreateStoreQueryParameter("@status", status)};

var list = await repository.ModelObjectContext.ExecuteStoreQueryAsync<UserPasswordEntity>(
            commandText,
            options,
            parameters);

I came across this error converting synchronous code to async. There is a synchronous method which takes MergeOption as a parameter.

EF version: 6.1.3
Operating system: Windows 10
Visual Studio version: VS 2015

Other details about my project setup:

Copied from original issue: dotnet/efcore#6503

Execution strategy retry executed N^2 times for connections

SaveChanges executes it's operations inside the current execution strategy.
However, the first thing it does is make a connection, which also executes inside the current execution strategy.

This means that, in practice, when it can't connect, the retries execute N^2 times instead of the 'N' defined by the strategy.

We observed this when having an Azure SQL transient unavailability. We had configured the default strategy (SqlAzureExecutionStrategy) which is 5 retries and ~26 seconds. But in practice we saw it retrying for 90 seconds (after which the database became available again and the retry succeeded).

ObjectContext.SaveChangesInternal
entriesAffected = executionStrategy.Execute(
() => SaveChangesToStore(options, executionStrategy, startLocalTransaction: true));

calls SaveChangesToStore
calls ExecuteInTransaction
calls EnsureConnection
calls EntityConnection.Open()
DbProviderServices.GetExecutionStrategy(_storeConnection, metadataWorkspace).Execute(
() => DbInterception.Dispatch.Connection.Open(_storeConnection, InterceptionContext));

Force history update on snapshot.

I'm currently working on a project where multiple developers are adding migrations into source control at the same time using EF6 CF. Both of the developers will make a change to their migrations, but when the second one merges in the code from the first, their migrations don't contain the correct snapshot, causing the Update-Database to fail due to pending migrations (although they are covered by the merged-in migrations).

Examples:

http://stackoverflow.com/questions/19136066/why-does-add-migration-sometimes-create-duplicate-migrations

http://stackoverflow.com/questions/17921886/update-database-fails-due-to-pending-changes-but-add-migration-creates-a-duplic

I wasn't sure if there was currently a way to fix this issue other than to create an empty migration to get a valid snapshot of the state of the system.

If there is not, I propose that a command is added that allows a developer to force-update the history tracking on the latest migration so that the Update-Database command will be better able to determine if there are really pending changes or not.

Note that this would also be a problem if you were to copy/paste a migration into your migrations folder -- so it's not necessary limited to developer teams.

Weakness regarding groupings over left joins

Consider this query:

from e in db.MyEntities

join o in db.MyOtherEntities
on e.Foo equals o.Foo into others
from o in others.DefaultIfEmpty()

// where e.Value1 == e.Value1 (see below)

select new
{
  Value1 = e.Value1,
  Value2 = o.Value2
}

It's one of the ways to write a left join, the one that also works in linq to objects.

When you call this query query and do a group by over it like this:

from e in query group e by new { } into g select g.Count()

you get a NotSupportedException:

The nested query is not supported. Operation1='GroupBy' Operation2='MultiStreamNest

If, however, the commented-out where clause above is put in, it works.

It also works if the group-by groups on something constant from the source itself:

from e in query group e by e.SomePropertyThatsActuallyConstant into g select g.Count()

And finally it works when the original query is rewritten as a subquery:

from e in db.MyEntities
from o in db.MyOtherEntities.Where(o => o.Foo == e.Foo).DefaultIfEmpty()

Why is this bizarre query important you ask?

I came across this while using DevExpress's DevExtreme.AspNet.Data library that is used to connect an in-browser data grid to a linq-based data source.

query is what I put in, the grouping is what the data library put on top.

I believe the way it does the somewhat bizarre grouping over a new { } is actually a natural way to implement total summaries in those cases where you also want to implement group summaries. The problem then manifests if you have total summaries, but no group summaries (which would otherwise appear in the now trivial new { }

While libraries like DevExtreme.AspNet.Data could work around it, and users like me can work around it, it's a headache especially for those not aware of what's going on.

So in conclusion, I think think it's best if this is solved on the entity framework level. Apparently entity framework has no fundamental problem doing the query, otherwise the workarounds wouldn't be so simple.

For the sake of completeness, here's the pull request I originally put on DevExtreme.AspNet.Data and there's a ticket on the DevExpress ticket system lamenting the same thing.

I put up a StackOverflow Q/A to educate about the workarounds for users.

Migrations use local time

When using Add-Migration the generated timestamp uses local time

Normally this is fine but if you have a distributed team then this can generate migrations to be applied out of order.

Is it possible too make a variation of Add-Migration that will generate the timestamp using UTC

e.g. Add-MigrationUtc

I am happy to implement it if given the okay that this is a useful feature.

.NET/EF6 ObjectContext leak using compiled LINQ query that references String.StartsWith()

Repro:

class Program
{
    static void Main(string[] args)
    {
        var test = new Test();
        test.Run();

        GC.WaitForPendingFinalizers();
        GC.Collect();

        Console.WriteLine("set breakpoint here -> Diagnostic Tools -> Take Snapshot -> View Heap -> context still rooted");
        Console.ReadKey();
    }
}

public class Test
{
    public void Run()
    {
        using (var context = new Model1Container())
        {
            var sec1 = new Security { SysRowID = Guid.NewGuid(), Company = "Contoso", SecCode = "Foo" };
            var sec2 = new Security { SysRowID = Guid.NewGuid(), Company = "Contoso", SecCode = "Bar" };
            var sec3 = new Security { SysRowID = Guid.NewGuid(), Company = "Microsoft", SecCode = "Foo" };

            context.AddToSecurities(sec1);
            context.AddToSecurities(sec2);
            context.AddToSecurities(sec3);

            context.SaveChanges();
        }

        using (var context = new Model1Container())
        {
            Expression<Func<Model1Container, string, string, IEnumerable<Security>>> expression =
                (ctx, company, token) =>
                (from row in ctx.Securities
                 where row.Company == company && row.SecCode.StartsWith(token)
                 select row);

            var query = CompiledQuery.Compile(expression);
            var result = query(context, "Contoso", "Foo").ToList();
        }
    }
}

Model:

public partial class Model1Container : ObjectContext
{
    public Model1Container() : base("name=Model1Container", "Model1Container")
    {
        this.ContextOptions.LazyLoadingEnabled = true;
        OnContextCreated();
    }

    partial void OnContextCreated();

    public ObjectSet<Security> Securities
    {
        get
        {
            if ((_Securities == null))
            {
                _Securities = base.CreateObjectSet<Security>("Securities");
            }
            return _Securities;
        }
    }
    private ObjectSet<Security> _Securities;

    public void AddToSecurities(Security security)
    {
        base.AddObject("Securities", security);
    }
}

[EdmEntityTypeAttribute(NamespaceName="Model1", Name="Security")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class Security : EntityObject
{
    public static Security CreateSecurity(global::System.Guid sysRowID, global::System.String company, global::System.String secCode)
    {
        Security security = new Security();
        security.SysRowID = sysRowID;
        security.Company = company;
        security.SecCode = secCode;
        return security;
    }

    [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.Guid SysRowID
    {
        get
        {
            return _SysRowID;
        }
        set
        {
            if (_SysRowID != value)
            {
                OnSysRowIDChanging(value);
                ReportPropertyChanging("SysRowID");
                _SysRowID = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("SysRowID");
                OnSysRowIDChanged();
            }
        }
    }
    private global::System.Guid _SysRowID;
    partial void OnSysRowIDChanging(global::System.Guid value);
    partial void OnSysRowIDChanged();

    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.String Company
    {
        get
        {
            return _Company;
        }
        set
        {
            OnCompanyChanging(value);
            ReportPropertyChanging("Company");
            _Company = StructuralObject.SetValidValue(value, false);
            ReportPropertyChanged("Company");
            OnCompanyChanged();
        }
    }
    private global::System.String _Company;
    partial void OnCompanyChanging(global::System.String value);
    partial void OnCompanyChanged();

    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.String SecCode
    {
        get
        {
            return _SecCode;
        }
        set
        {
            OnSecCodeChanging(value);
            ReportPropertyChanging("SecCode");
            _SecCode = StructuralObject.SetValidValue(value, false);
            ReportPropertyChanged("SecCode");
            OnSecCodeChanged();
        }
    }
    private global::System.String _SecCode;
    partial void OnSecCodeChanging(global::System.String value);
    partial void OnSecCodeChanged();
}

Add VS2015 support to Power Tools VSIX

EF power tools are not listed as an extension for Visual Studio 2015. The VSIX needs to be updated with
<VisualStudio Version-"14.0">
Pro

I've been using a modified VSIX but have only used it for View Entity Data Model (Read-Only) feature. Not sure if there are other known problems.

Breaking Change: Query crashes when compiled with VS2015 RTM (Roslyn compiler)

The following query crashes when compiled with VS2015 RTM, but works when compiled with the old compiler in VS2013:

public async Task<List<ProductRelation>> FailingQuery(SampleEnum queryOption)
        {
            using (var context = new SampleContext())
            {

                int[] ids = await Task.FromResult(new[] { 1, 2, 3, 4 });
                return await (from order in context.Set<Order>()
                              where ids.Contains(order.OrderId)
                                 && queryOption == SampleEnum.Value1
                              from pr in context.Set<ProductRelation>()
                              select pr).ToListAsync();
            }
        }

(Not that the query has been simplified for demonstration purposes, it obviously makes no sense in this shape but I have reduced it as much as possible).

Exception: 

System.NotSupportedException: LINQ to Entities does not recognize the method 'System.Data.Entity.DbSet`1[RoslynEfTest.UnitTest1+ProductRelation] Set[ProductRelation]()' method, and this method cannot be translated into a store expression.

I have attached a sample unit-test project which illustrates the error.

Default constraint isn't being dropped before altering column which causes an error

One of my enums was created using byte and now I'm trying to switch it to int. I'm getting an error because the default constraint added for this column isn't being dropped before altering the column. I believe this is the same issue as dotnet/efcore#1345

The results of running the migration are

Applying explicit migration: 201608250548579_update enum data type to int.
ALTER TABLE [dbo].[AgencyAgreements] ALTER COLUMN [Status] [int] NOT NULL
ALTER TABLE [dbo].[Transactions] ALTER COLUMN [BillOfSale_Status] [int] NOT NULL
System.Data.SqlClient.SqlException (0x80131904): The object 'DF__Transacti__BillO__4E88ABD4' is dependent on column 'BillOfSale_Status'.
ALTER TABLE ALTER COLUMN BillOfSale_Status failed because one or more objects access this column.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext)
   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery()
   at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(MigrationStatement migrationStatement, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(MigrationStatement migrationStatement, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinTransaction(IEnumerable`1 migrationStatements, DbTransaction transaction, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinNewTransaction(IEnumerable`1 migrationStatements, DbConnection connection, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection, DbInterceptionContext interceptionContext)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection)
   at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClass30.<ExecuteStatements>b__2e()
   at System.Data.Entity.Infrastructure.DbExecutionStrategy.<>c__DisplayClass1.<Execute>b__0()
   at System.Data.Entity.Infrastructure.DbExecutionStrategy.Execute[TResult](Func`1 operation)
   at System.Data.Entity.Infrastructure.DbExecutionStrategy.Execute(Action operation)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements, DbTransaction existingTransaction)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, VersionedModel targetModel, IEnumerable`1 operations, IEnumerable`1 systemOperations, Boolean downgrading, Boolean auto)
   at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
   at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
   at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
   at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
   at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
ClientConnectionId:5befeded-6fb9-427c-aa92-84698dbfe816
Error Number:5074,State:1,Class:16
The object 'DF__Transacti__BillO__4E88ABD4' is dependent on column 'BillOfSale_Status'.
ALTER TABLE ALTER COLUMN BillOfSale_Status failed because one or more objects access this column.

Issue #1

sorry, couldn't resist! And thanks for putting EF6 over here on github! :)

Simplify transaction handling samples

Our current set of documentation for using transactions with EF6 includes some samples that follow this pattern:

using (var context = new BloggingContext()) 
{ 
    using (var dbContextTransaction = context.Database.BeginTransaction()) 
    { 
        try 
        { 
            DoSomeWork(context);
            context.SaveChanges(); 
            dbContextTransaction.Commit(); 
        } 
        catch (Exception) 
        { 
            dbContextTransaction.Rollback(); 
        } 
    } 
} 

It turns out that:

  1. The explicit call to dbContextTransaction.Rollback() is in most cases unnecessary, because disposing the transaction at the end of the using block will take care of rolling back.
  2. If an error of sufficient severity occurs in SQL Server, the transaction will get automatically rolled back, and the call to dbContextTransaction.Rollback() in the catch block will actually fail.

For the second, note that our implementation of Rollback() simply delegates to the ADO.NET provider Rollback() method so the following note from the remarks in the underlying method's documentation apply:

Try/Catch exception handling should always be used when rolling back a transaction. A Rollback generates an InvalidOperationException if the connection is terminated or if the transaction has already been rolled back on the server.

The sample code has proven to be confusing at least for one of our customers and relying on the automatic rollback behavior of disposing without first calling Commit() works more reliably and leads to simpler code, so I propose we fix the samples to use that pattern:

using (var context = new BloggingContext()) 
{ 
    using (var dbContextTransaction = context.Database.BeginTransaction()) 
    { 
        DoSomeWork(context);
        context.SaveChanges(); 
        dbContextTransaction.Commit(); 
    } 
} 

Note that this pattern applies to EF Core 1.0 as well, when we write the corresponding documentation.

SqlFunctions.CharIndex Incorrect Parameter Order

Seen in Version 6.1.3

The parameters for SqlFunction.CharIndex are documented as:

// Summary:
//     Returns the starting position of one expression
//     found within another expression.
//
// Parameters:
//   toSearch:
//     The string expression to be searched.
//
//   target:
//     The string expression to be found.
//
// Returns:
//     The starting position of target if it is found in toSearch .
//
public static int? CharIndex(string toSearch, string target);

However, given the results below, it appears the parameters need to be swapped around in order to achieve the desired functionality.

// Called as documented, string to search "ABCDEFG", string to be found "D"
DbContext.Items.Select(o => SqlFunctions.CharIndex("ABCDEFG", "D"));

//Expected Result: 4
//Actual Result: 0

// Called with parameters swapped
DbContext.Items.Select(o => SqlFunctions.CharIndex("D", "ABCDEFG"));

//Result: 4

This is also the case for the other 5 overloaded methods.

Database first - ability to override default type mapping

i have simple table in MS SQL containing 2 columns:
ClientId - binary(8) primary key
ClientName - varchar(30)

When I add that table to my model I can see that ClientId type = Binary

snap 2016-07-29 at 09 26 38

What I would like to do is to override that type so that inside C# code I will be able to use int instead of byte[].

SELECT * FROM Clients WHERE ClientId = 0x0000000000000001 and SELECT * FROM Clients WHERE ClientId = 1 are giving me same results so why not allow to specify target mapping.

This would only require simple CAST inside SQL and just for select operation, all other work fine.

I'm aware I can use stored procedures for select and updates or even use SQL view. But sometimes for very simple applications this would be big convenience.

It's easier to say client with Id = 4067 than client with Id =0x0000000000000FE3

Can this be done?

I've posted same issue in EF7 issue tracker. Currently I'm using EF 6.1.3 so I'd like to have this working it that version, but at some point I'll be moving to EF Core so I'd also like that feature working there.

EntityFramework package (not core), has bad frameworkassembly values

From @rrelyea on August 8, 2016 21:5

Steps to reproduce

originally filed as: NuGet/Home#3279
Repro Steps:

  1. Create a new project C#-> Windows 8->Windows Runtime Component (Windows 8.1).
  2. Right-click the project node and click "Manage NuGet Packages…" menu to start package manager.
  3. Install package “EntityFramework”, and verify it can be installed.

Expected Result:
The package “EntityFramework” can be installed correctly.

Actual Result:
The package “EntityFramework” can’t be installed as below screenshot.

untitled841

Note:
It happened on Dev14 U3+NuGet Dev 1731(3.6.0.1731).
It repro on any version of package “EntityFramework”.
It also repro on Dev14 U3 (NuGet 3.4.4.1321).

The issue

NuGet sees
<FrameworkAssembly ... TargetFramework="" />
TargetFramework should not be empty, but should be Net40 or Net45.

When you don't specify a framework, nuget thinks this works in all TFMs. Thus the package seemed to install on this Win8.1 project, while it should fail.

Further technical details

None.

Copied from original issue: dotnet/efcore#6272

We sometimes expose PK values in exception messages

Some exceptions contain information about Entity Key value. This may be a security concern, if the key is not surrogate. We should consider not exposing those values via exception messages

comments

maumar wrote Jul 24, 2015 at 3:46 PM [x]

Examples of messages that reveal PK values:

Materializer_RecyclingEntity - "All objects in the EntitySet '{0}' must have unique primary keys. However, an instance of type '{1}' and an instance of type '{2}' both have the same primary key value, '{3}'. "

Materializer_AddedEntityAlreadyExists - "An object with a key value '{0}' already exists in an added state. An object in this state cannot be merged."

Intermittent IIS App Pool Crash using EntityFramework 6.1.3

We have an ongoing issue where our w3wp.exe process crashing intermittently on a ASP.NET MVC controller method that is executing a complicated linq query against EntityFramework 6.1.3.

We have enabled DebugDiag (2.2) on the server to capture dump files. The dump files show a Second Chance Exception of type AccessViolationException when loaded into WinDbg. With SOS extensions loaded !clrstack shows very little information, only 2 GCFrame lines. There is also an unmanaged stack trace when using !dumpstack that just appears to be raising the exception.

Recently DebugDiag was configured with a rule to produce a dump on First Chance Exceptions of type StackOverflow. Analyzing the dump with symbols loaded produces the attached from WinDbg when executing !dumpstack -EE.

There seems to be a problem in EntityFramework where it is calling ExpressionConverter+ConstantTranslator.TypedTranslate for a portion of our query. When examining the managed and unmanaged stack using !dumpstack there are many repeating calls to exception raising code in the unmanaged portion of the stack.

When we view the stack objects with !dso we seem to consume the stack with references to the same System.Linq.Enumerable+WhereSelectEnumerableIterator object.

This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(b134.c04c): Stack overflow - code c00000fd (first/second chance not available)
clr!AdjustContextForWriteBarrier+0xb2:
000007fc'91344336 e815d3caff      call    clr!_security_check_cookie (000007fc'90ff1650)

!dso
OS Thread Id: 0xc04c (81)
RSP/REG          Object           Name
00000047037A75F0 00000045c8bc74b8 System.Linq.Enumerable+WhereSelectEnumerableIterator'2[[MyCompany.Entities.CurriculumGroupCourse, MyCompany.Entities],[System.Guid, mscorlib]]
00000047037A7670 00000045c8bc74b8 System.Linq.Enumerable+WhereSelectEnumerableIterator'2[[MyCompany.Entities.CurriculumGroupCourse, MyCompany.Entities],[System.Guid, mscorlib]]
00000047037A7688 00000045c8bc74b8 System.Linq.Enumerable+WhereSelectEnumerableIterator'2[[MyCompany.Entities.CurriculumGroupCourse, MyCompany.Entities],[System.Guid, mscorlib]]
00000047037A7690 00000045c83abc30 <Unloaded Type>
  • This repeats many many times:
00000047037A7698 00000045c83abc30 <Unloaded Type>
00000047037A76B8 0000004682332d18 System.RuntimeType
00000047037A76C8 000000454275cb70 System.Reflection.RuntimeMethodInfo
00000047037A76D0 00000045c8c39530 System.Linq.Expressions.LogicalBinaryExpression
00000047037A7C50 00000045c8bc74b8 System.Linq.Enumerable+WhereSelectEnumerableIterator'2[[MyCompany.Entities.CurriculumGroupCourse, MyCompany.Entities],[System.Guid, mscorlib]]
00000047037A7CD0 00000045c8bc74b8 System.Linq.Enumerable+WhereSelectEnumerableIterator'2[[MyCompany.Entities.CurriculumGroupCourse, MyCompany.Entities],[System.Guid, mscorlib]]
00000047037A7CE8 00000045c8bc74b8 System.Linq.Enumerable+WhereSelectEnumerableIterator'2[[MyCompany.Entities.CurriculumGroupCourse, MyCompany.Entities],[System.Guid, mscorlib]]
00000047037A7CF0 00000045c83abc30 <Unloaded Type>
  • We have verified we don't have any recursive calls.
  • Calling the endpoint with the same URL does not reproduce the issue.
  • The crash happens when making the same query but with different paramaters.
  • We are not able to reproduce this in local environments, it only shows up on production.

It looks like there is a bug in EntityFramework which is causing the intermittent issue. Can the EF team provide any insight?

Attached is a dump of the managed stack.
WinDbgStack.txt

Conflicting configuration settings were specified for property 'MyProperty' on type 'MyType'. MaxLength = 100 conflicts with MaxLength = 200

Hi,

i have a big problem on using Complex Types on my entities.
I created a small repro for my issue. You can find it as an attachment.

The VS Solution is attached so that following Package Manager command can be executed without any errors.

Add-Migration -Name Initial -Force

You can see the generated output in 201605111247310_Initial.cs.
I configured a MaxLength for all strings to 50 (see MyContext.cs).
Then I configured one of the sub property (PropB) of MyEntity.First (this is a complex type) to have a max length of 100.

Up to here all works as expected.

Now I'm trying to configure property "PropB" for MyEntity.Second to have a max length of 200.

For that uncomment line 18 in MyEntityConfiguration.cs and run the following command again:

Add-Migration -Name Initial -Force

Now I get this error:

Conflicting configuration settings were specified for property 'PropA' on type 'ComplexTypeWithStringLength.MyComplexType' MaxLength = 100 conflicts with MaxLength = 200

I don't understand why!? Is this a bug?

Regards,
Daniel
ComplexTypeWithStringLength.zip

DatabaseLogFormatter logs incorrect sql query execution times

If you new up multiple DbContext and make queries in parallel, each context's DatabaseLogFormatter receives interception notifications of every other DbContext!
It confuses the DatabaseLogFormatter, which seems to have been written without that scenario in mind.
Therefore DatabaseLogFormatter will stop its StopWatch even though the event comes from the query from another context.
I guess it's a bug at the interception level. A DbContext should only received interceptions events relating to queries/commands issued against that particular context.
Sorry I don't have time to build a repro, but if that's not clear I can provide additional details...

Applying migrations to upgrade from EF5 to 6.1.2 fails for SqlCE (CodePlex work items 2807, 2659)

This is the same bug as work item 2807 on CodePlex.

Recapitulation:

Per work item 2659:

The exception System.Data.SqlServerCe.SqlCeException (0x80004005): The foreign key constraint does not exist. [ PK___MigrationHistory ]
is thrown when attempting a migration of a SqlCE database created in EF5 to EF6.1.2.

This problem is related to workitem 2523. The fix introduced for this workitem appears flawed.

I have a SQLCE database created in EF5 and its __MigrationHistory table uses a primary key constraint name of PK_db0.__MigrationHistory.
When migrating the database to EF6.1.2 the update-database command updates the __MigrationHistory table using the SQL statements:

ALTER TABLE [__MigrationHistory] ADD [ContextKey] nvarchar NOT NULL DEFAULT 'My.Database.Migrations.Configuration'
GO

ALTER TABLE [__MigrationHistory] DROP CONSTRAINT [PK___MigrationHistory]
GO

ALTER TABLE [__MigrationHistory] ALTER COLUMN [MigrationId] nvarchar NOT NULL
GO

ALTER TABLE [__MigrationHistory] ADD CONSTRAINT [PK___MigrationHistory] PRIMARY KEY ([MigrationId], [ContextKey])
GO

The second SQL statement ALTER TABLE [__MigrationHistory] DROP CONSTRAINT [PK___MigrationHistory]
throws an exception as the constraint name should be PK_db0.__MigrationHistory.

This is the CREATE script for the __MigrationHistory table from my SqlCE database as it was originally created using EF5:

CREATE TABLE [__MigrationHistory]([MigrationId] nvarchar%28255%29 NOT NULL
, [Model] image NOT NULL
, [ProductVersion] nvarchar%2832%29 NOT NULL);
GO
ALTER TABLE [__MigrationHistory] ADD CONSTRAINT [PK_dbo.__MigrationHistory] PRIMARY KEY ([MigrationId]);
GO

My theory is that the SqlCE database can have a constraint name of either PK___MigrationHistory or PK_dbo.__MigrationHistory depending up which version of EF created the database, so the SQL statements for migrating the MigrationHistory to EF6.1.2 must be able to cope with either naming convention.

That work item was closed as avoidable:

I'm going to close this issue as it can be worked around by upgrading EF 5.0.0 => EF 6.0.0 => EF 6.1.2".

My work item pointed out that this did not fix every legitimate scenario:

We ship a desktop application using EF and SQL CE and perform migrations programmatically as needed - we can't easily perform a disjointed upgrade (going from 5 to 6 to 6.1.2, migrating at each step) as the work item resolution suggests. It would be much more more helpful if the migration table code was updated to cover all historical scenarios.

It looks like I'll have to stick with EF 5.0.0 until there are newer versions that can actually cleanly support upgrading.

and @rowanmiller commented with:

EF Team Triage: Agreed - you should be able to go from 5 -> 6.x. Assigning to 6.2 to add logic to detect and support a v5 -> vCurrent upgrade.

I am reopening it here since the work item was closed instead of migrated and the bulk message noted that new issues could be opened. Is this still on the radar for any future release?

SQL Server 2016 and EntityFramework 6.1.3 Datetime change detection issue

We recently upgraded to SQL Server 2016 and have found a compatibility issue with EF 6.1.3 Code First. What we're seeing is that datetime data types are being detected as changed, when they haven't actually changed, which is causing records to be written to the database when they shouldn't, which is causing concurrency exceptions when we check against timestamps.

If we change the database compatibility to 2014, everything works as expected.

When in 2016 compatibility mode, the following sql statement will be generated by EF, but this statement does not appear when running against previous versions of SQL Server. Note that the field in question (StateLastChangedDate) is NOT changing:

exec sp_executesql N'UPDATE [dbo].[TranslationTarget]
SET [StateLastChangedDate] = @0
WHERE (([Id] = @1) AND ([LastEdited] = @2))
SELECT [LastEdited]
FROM [dbo].[TranslationTarget]
WHERE @@rowcount > 0 AND [Id] = @1',N'@0 datetime2(7),@1 uniqueidentifier,@2 binary(8)',@0='2016-08-19 14:36:31.1233333',@1='725DE153-266D-43A1-9811-D63FEE3DFA22',@2=0x0000000000002AC4

The fields are defined as:

[StateLastChangedDate] [datetime] NULL
[LastEdited] [timestamp] NOT NULL

When we look at our audit records, we see repeated updates for that table, all with exactly the same values, other than the RowVersion column.

For example, a single update produce the following StateLastChangedDate updates (note how they're all the same):
2016-08-19 14:36:31.123
2016-08-19 14:36:31.123
2016-08-19 14:36:31.123
2016-08-19 14:36:31.123
2016-08-19 14:36:31.123

Help? :)

Sequence contains more than one element - 2 joins between entities using stored procedure mappings

Hi,

I get the error "Sequence contains more than one element" when joining the same 2 entities twice and using MapToStoredProcedures(). See the code below. If you remove the MapToStoredProcedure() calls in the configuration classes, then the code runs.

public class TableOne
{
    public int TableOneId { get; set; }
    public virtual TableTwo TableTwo_1 { get; set; }
    public virtual TableTwo TableTwo_2 { get; set; }
}

public class TableTwo
{
    public int TableTwoId { get; set; }
}

public class TableOneMap : EntityTypeConfiguration<TableOne>
{
    public TableOneMap()
    {
        // Primary Key
        HasKey(t => t.TableOneId);

        // Relationships
        HasRequired(t => t.TableTwo_1)
            .WithMany()
            .Map(d => d.MapKey("TableTwoId_1"))
            .WillCascadeOnDelete(false);

        HasRequired(t => t.TableTwo_2)
            .WithMany()
            .Map(d => d.MapKey("TableTwoId_2"))
            .WillCascadeOnDelete(false);

        MapToStoredProcedures();
    }
}

public class TableTwoMap : EntityTypeConfiguration<TableTwo>
{
    public TableTwoMap()
    {
        // Primary Key
        HasKey(t => t.TableTwoId);

        MapToStoredProcedures();
    }
}

public class EFTestContextSeedIntialiser : DropCreateDatabaseAlways<EFTestContext>
{
    protected override void Seed(EFTestContext context)
    {
        var table2_1 = new TableTwo();
        var table2_2 = new TableTwo();

        var table1 = new TableOne()
        {
            TableTwo_1 = table2_1,
            TableTwo_2 = table2_2
        };

        context.Set<TableOne>().Add(table1);
        context.SaveChanges();
    }
}

public class EFTestContext : DbContext
{
    public EFTestContext()
        : base("Name=EFTestContext")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new TableOneMap());
        modelBuilder.Configurations.Add(new TableTwoMap());
    }
}


class Program
{
    static void Main(string[] args)
    {
        Database.SetInitializer(new EFTestContextSeedIntialiser());
        var context = new EFTestContext();
        context.Database.Initialize(true);

        System.Console.WriteLine("First Join: " + context.Set<TableOne>().First().TableTwo_1.TableTwoId);
        System.Console.WriteLine("Second Join: " + context.Set<TableOne>().First().TableTwo_2.TableTwoId);

        System.Console.ReadLine();
    }
}

A first chance exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll
System.Transactions Critical: 0 : http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/UnhandledUnhandled exceptionConsole.vshost.exeSystem.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089Sequence contains more than one element at System.Linq.Enumerable.SingleOrDefaultTSource
at System.Data.Entity.Migrations.Infrastructure.ModificationCommandTreeGenerator.ChangeRelationshipStates(DbContext context, EntityType entityType, Object entity, EntityState state)
at System.Data.Entity.Migrations.Infrastructure.ModificationCommandTreeGenerator.d__14.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Linq.Enumerable.d__b11.MoveNext()
at System.Linq.Buffer1..ctor(IEnumerable1 source)
at System.Linq.Enumerable.ToArrayTSource
at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.GenerateFunctionBodyTCommandTree
at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.GenerateUpdateFunctionBody(EntityTypeModificationFunctionMapping modificationFunctionMapping, Lazy1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator) at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.d__15f.MoveNext() at System.Linq.Enumerable.d__313.MoveNext()
at System.Linq.Enumerable.d__711.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(ModelMetadata source, ModelMetadata target, Lazy1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator, String sourceModelVersion, String targetModelVersion) at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(XDocument sourceModel, XDocument targetModel, Lazy1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator, String sourceModelVersion, String targetModelVersion)
at System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable1 pendingMigrations, String targetMigrationId, String lastMigrationId) at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Upgrade(IEnumerable1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.b__b()
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update()
at System.Data.Entity.Internal.DatabaseCreator.CreateDatabase(InternalContext internalContext, Func3 createMigrator, ObjectContext objectContext) at System.Data.Entity.Internal.InternalContext.CreateDatabase(ObjectContext objectContext, DatabaseExistenceState existenceState) at System.Data.Entity.Database.Create(DatabaseExistenceState existenceState) at System.Data.Entity.DropCreateDatabaseAlways1.InitializeDatabase(TContext context)
at System.Data.Entity.Internal.InternalContext.<>c__DisplayClassf1.b__e() at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action) at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization() at System.Data.Entity.Database.Initialize(Boolean force) at Console.Program.Main(String[] args) in c:\Users\ajohnc\Documents\Visual Studio 2013\Projects\EFPowerToolsTest\Console\Program.cs:line 91 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()System.InvalidOperationException: Sequence contains more than one element at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable1 source)
at System.Data.Entity.Migrations.Infrastructure.ModificationCommandTreeGenerator.ChangeRelationshipStates(DbContext context, EntityType entityType, Object entity, EntityState state)
at System.Data.Entity.Migrations.Infrastructure.ModificationCommandTreeGenerator.d__14.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext() at System.Linq.Enumerable.d__b11.MoveNext()
at System.Linq.Buffer1..ctor(IEnumerable1 source)
at System.Linq.Enumerable.ToArrayTSource
at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.GenerateFunctionBodyTCommandTree
at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.GenerateUpdateFunctionBody(EntityTypeModificationFunctionMapping modificationFunctionMapping, Lazy1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator) at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.d__15f.MoveNext() at System.Linq.Enumerable.d__313.MoveNext()
at System.Linq.Enumerable.d__711.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(ModelMetadata source, ModelMetadata target, Lazy1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator, String sourceModelVersion, String targetModelVersion) at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(XDocument sourceModel, XDocument targetModel, Lazy1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator, String sourceModelVersion, String targetModelVersion)
at System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable1 pendingMigrations, String targetMigrationId, String lastMigrationId) at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Upgra

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.