2008-08-18 7 views
9

J'utilise un modèle de référentiel avec LINQ, avec IRepository.DeleteOnSubmit (Entité T). Il fonctionne très bien, mais quand ma classe d'entité possède une interface, comme ceci:LINQ, entité qui implémente l'interface et l'exception dans le mappage

public interface IEntity { int ID {get;set;} } 

public partial class MyEntity: IEntity { 

    public int ID { 
     get { return this.IDfield; } 
     set { this.IDfield=value; } 
    } 
} 

puis essayer de supprimer une entité comme ceci:

IEntity ie=repository.GetByID(1); 
repoitory.DeleteOnSubmit(ie); 

lancers francs
Le membre « IEntity.ID » a pas de traduction supportée vers SQL.

l'extraction des données à partir de la base de données, mais pas de la suppression et de l'insertion. Comment utiliser l'interface avec DataContext?


Ici, il est:
Message d'exception: Le membre 'MMRI.DAL.ITag.idContent' n'a pas de traduction pris en charge à SQL.

code:

var d = repContent.GetAll().Where(x => x.idContent.Equals(idContent)); 
foreach (var tagConnect in d) <- error line 
{ 
    repContet.DeleteOnSubmit(tagConnect); 

(il obtient tous les tags de DB, et les supprime)

Et trace de la pile:

[NotSupportedException: The member 'MMRI.DAL.ITag.idContent' has no supported translation to SQL.] 
    System.Data.Linq.SqlClient.Visitor.VisitMember(SqlMember m) +621763 
    System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) +541 
    System.Data.Linq.SqlClient.SqlVisitor.VisitExpression(SqlExpression exp) +8 
    System.Data.Linq.SqlClient.SqlVisitor.VisitBinaryOperator(SqlBinary bo) +18 
    System.Data.Linq.SqlClient.Visitor.VisitBinaryOperator(SqlBinary bo) +18 
    System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) +196 
    System.Data.Linq.SqlClient.SqlVisitor.VisitExpression(SqlExpression exp) +8 
    System.Data.Linq.SqlClient.SqlVisitor.VisitSelectCore(SqlSelect select) +46 
    System.Data.Linq.SqlClient.Visitor.VisitSelect(SqlSelect select) +20 
    System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node) +1024 
    System.Data.Linq.SqlClient.SqlProvider.BuildQuery(... 

Lorsque je tente faire décorer la classe partielle:

[Column(Storage = "_idEvent", DbType = "Int NOT NULL", IsPrimaryKey = true)] 
public int idContent 
{ get { return this.idEvent; } set { this.idEvent=value; } } 

il throws error "Nom de colonne invalide 'idContent'."

+2

Le dépassement de pile n'est pas un forum. Certaines des choses que vous (et d'autres) avez posté comme "réponse" à la question devraient être des "commentaires". Vous pouvez également modifier la question d'origine et toute réponse. – jeroenh

Répondre

0

Essayez ceci:

using System.Data.Linq.Mapping; 

public partial class MyEntity: IEntity 
{ [Column(Storage="IDfield", DbType="int not null", IsPrimaryKey=true)] 
     public int ID 
     {   
      get { return this.IDfield; }   
      set { this.IDfield=value; }  
     } 
} 
3

Cela fonctionne pour moi -

public partial class MyEntity: IEntity 
{ [Column(Name = "IDfield", Storage = "_IDfield", IsDbGenerated = true)] 
     public int ID 
     {   
      get { return this.IDfield; }   
      set { this.IDfield=value; }  
     } 
} 
+1

Il y a des problèmes avec faire ce qui précède, malheureusement - http://social.msdn.microsoft.com/Forums/en-US/linqtosql/thread/5691e0ad-ad67-47ea-ae2c-9432e4e4bd46 Il y a un lien vers un bug enregistré à MS Connect au bas de cette page. J'espère que certains d'entre vous peuvent voter pour qu'il puisse être regardé - c'est un problème qui m'ennuie depuis un moment maintenant ... –

0

Pour traduire votre requête LINQ to SQL réelle, l'expression Linq2SQL inspecte que vous lui donnez. Le problème est que vous n'avez pas fourni suffisamment d'informations pour que L2S puisse traduire la propriété "ID" en nom de colonne DB réel. Vous pouvez obtenir ce que vous voulez en vous assurant que L2S peut associer "ID" à "IDField".

Ceci devrait être possible en utilisant l'approche fournie dans les réponses. Si vous utilisez le concepteur, vous pouvez simplement renommer la propriété de classe "IDField" en "ID", avec l'avantage supplémentaire que vous n'aurez plus à implémenter explicitement la propriété "ID" dans votre classe partielle, à-dire la définition de classe partielle pour MyEntity devient simplement:

public partial class MyEntity: IEntity 
{  
} 
7

il semble Microsoft a supprimé le support pour == opérateur lors de l'utilisation des interfaces LINQ to SQL dans MVC4 (ou peut-être il n'a jamais été pris en charge). Vous pouvez cependant utiliser i.ID.Equals(someId) à la place de l'opérateur ==.

Coulée IQueryable à IEnumerable fonctionne mais ne doit pas être utilisé! La raison est: IQueryable a l'implémentation funky de IEnumerable.Quelle que soit la méthode linq que vous utiliserez sur un IQueryable via l'interface IEnumerable, la requête sera exécutée en premier, tous les résultats seront récupérés en mémoire à partir de la base de données et éventuellement exécutés localement sur les données (normalement, ces méthodes seront traduites) SQL et exécuté dans la base de données). Imaginez que vous essayiez d'obtenir une seule ligne à partir d'une table contenant un milliard de lignes, en les récupérant toutes pour en choisir une (et cela devient bien pire avec un casting négligent de IQueryable à IEnumerable et des données relatives au chargement paresseux).

Apparemment Linq n'a aucun problème en utilisant == opérateur avec des interfaces sur les données locales (donc seulement est affecté) et aussi avec Entity Frameworks (ou si j'ai entendu).

+0

Il est vraiment étrange que '==' ne soit pas supporté. De toute façon, merci pour la réponse 'i.ID.Equals (someId)' fonctionne bien pour moi. – mykhailovskyi

Questions connexes