2008-08-18 8 views
9

私はLINQでリポジトリパターンを使用していますが、IRepository.DeleteOnSubmit(T Entity)を持っています。それは正常に動作しますが、私のエンティティクラスは、このようなインターフェースを有する場合:LINQ、マッピングでインターフェイスと例外を実装するエンティティ

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

public partial class MyEntity: IEntity { 

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

してから、このようないくつかのエンティティを削除しようとしている:

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


メンバーを投げる「IEntity.ID」はSQLへの変換はサポートされていません。

DBからのデータの取得は機能しますが、削除と挿入は機能しません。 DataContextに対するインターフェイスの使用方法


ここにある:
例外メッセージ: メンバー 'MMRI.DAL.ITag.idContent' SQLへのサポートの翻訳を持っていません。

コード:

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

(それはDBからの全てのタグを取得し、それらを削除します)

およびスタックトレース:

[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(... 

私は部分クラスを飾るんしようとすると

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

itエラーをスローする "無効な列名 'idContent'。"

+2

スタックオーバーフローはフォーラムではありません。あなた(そして他の人)が質問に「回答」として掲示したものは、実際には「コメント」でなければなりません。元の質問と回答を編集することもできます。 – jeroenh

答えて

0

これを試してみてください:

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

これが私の作品 - 実際のSQLにあなたのLINQクエリを翻訳するための

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

残念ながら上記を行うと問題があります - http://social.msdn.microsoft.com/Forums/en-US/linqtosql/thread/5691e0ad-ad67-47ea-ae2c-9432e4e4bd46へのリンクをあります そのページの下部にあるMS Connectに記録されたバグ。うまくいけばあなたが投票できるように投票できる人もいるかもしれません - それは今私をしばらく悩ませている問題です。 –

0

、Linq2SQLは、あなたがそれを与える表現を検査します。問題は、 "ID"プロパティを実際のDBカラム名に変換するためにL2Sに十分な情報を提供していないことです。 L2Sが "ID"を "IDField"にマップできるようにすることで、あなたが望むものを達成することができます。

これは、回答で提供されるアプローチを使用して可能になるはずです。

デザイナを使用する場合は、クラスプロパティ "IDField"の名前を "ID"に変更するだけで、部分クラスの "ID"プロパティを明示的に実装する必要がなくなります。すなわちMyEntityのための部分的なクラス定義は、単純に次のようになります。

public partial class MyEntity: IEntity 
{  
} 
7

MVC4でLINQツーSQLを使用した場合、Microsoftはインタフェースに==オペレータのサポートを落とし表示されます(または多分それはサポートされませんでした)。ただし、==演算子の代わりにi.ID.Equals(someId)を使用できます。

キャストIQueryable~IEnumerable作品ではなく、は使用しないでください。理由は:IQueryableIEnumerableのファンキーな実装を持っています。IQueryableIEnumerableインターフェイスで使用するlinqメソッドは、クエリが最初に実行され、すべての結果がDBからメモリにフェッチされ、最終的にはデータにlocalyメソッドが実行されます(通常、これらのメソッドは変換されます)。 SQLに変換してDBで実行します)。 10億行を含むテーブルから1行を取り出し、すべてを取り出して1つだけ取り出しようとしていると想像してください(IQueryableからIEnumerableへの不注意なキャストとレイジーローディング関連のデータではさらに悪化します)。

Linqはローカルデータのインターフェイスを持つ==演算子を使用しているので問題はありません(したがって、IQueryableのみが影響を受けます)。

+0

'=='はサポートされていないのは本当に奇妙です。とにかく、答え 'i.ID.Equals(someId)'のおかげでうまく動作します。 – mykhailovskyi

関連する問題