2014-10-13 7 views
15

Sto usando il metodo sovraccarico in Assembly A:strano "assemblea non fa riferimento" l'errore quando si cerca di chiamare un metodo di sovraccarico valida

public static int GetPersonId(EntityDataContext context, string name) 
{ 
    var id = from ... in context... where ... select ...; 
    return id.First(); 
} 

public static int GetPersonId(SqlConnection connection, string name) 
{ 
    using (var context = new EntityDataContext(connection, false)) 
    { 
     return GetPersonId(context, name); 
    } 
} 

Quando provo a chiamare il secondo di sovraccarico da Assembly B, VS produce i seguenti compilazione errore di -time:

The type 'System.Data.Entity.DbContext' is defined in an assembly that is not referenced. You must add a reference to assembly 'EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=...'.

Assembly B riferimenti Assembly A. Entity Framework fa riferimento solo a Assembly A come Assembly B non lo utilizza. La chiamata da Assembly B assomiglia a questo:

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    connection.Open();        
    var id = AssemblyA.GetPersonId(connection, name); // compiler error 
    ... 
} 

Quello che non capisco è che l'errore va via se cambio il metodo firma in Assembly A per esempio:

public static int GetPersonId(SqlConnection connection, string name, bool empty) 

e modificare la chiamare a:

var id = AssemblyA.GetPersonId(connection, name, true); // no error 

Perché il mio codice non si sta compilando nel primo caso? Non sembra essere correlato a Entity Framework come indica l'errore. Ho sempre pensato che C# consente l'overloading dei metodi in cui le firme dei metodi differiscono solo nei tipi di parametri. Per esempio. Posso eseguire il seguente codice senza problemi come previsto:

static void DoStuff(int a, int b) { ... } 
static void DoStuff(int a, float b) { ... } 

DoStuff(10, 5); 
DoStuff(10, 5.0f); 

Allora perché sto ottenendo l'errore nella mia situazione, nonostante i sovraccarichi apparentemente legali?

Si noti che da Assembly B non ho problemi a chiamare altri metodi che utilizzano internamente EntityDataContext, l'unica differenza è che questi metodi non hanno sovraccarichi.


Sfondo

EntityDataContext eredita EF di DbContext:

public partial class EntityDataContext : DbContext 
{ 
     public EntityDataContext() : base("name=EntityDataContext") { } 

     public EntityDataContext(DbConnection connection, bool contextOwnsConnection) 
      : base(connection, contextOwnsConnection) { } 

     ... 
} 

sto usando .NET 4.0 con il codice di EF 6 prima a un database esistente con alcuni sovraccarichi ctor personalizzato aggiunto.

risposta

7

Lo standard C# specifica che la risoluzione di sovraccarico (sezione 7.5.3) viene eseguita confrontando ciascuna firma corrispondente per determinare quale sia l'adattamento migliore. Non dice cosa succede quando manca un riferimento, quindi dobbiamo dedurre che deve ancora confrontare quei tipi non referenziati.

Nel tuo caso, il compilatore necessita di un riferimento a EntityDataContext per poter confrontare i due sovraccarichi. La tua chiamata corrisponde esattamente alla firma, quindi in teoria non dovresti averne bisogno, ma lo standard non specifica alcun comportamento di cortocircuito.