私は、選択メニューを満たすために、sprocから最小限の結果を返すメソッドを持っています。最低限の結果が必要な場合は、bool getMin = trueをsprocに渡し、完全なレコードが必要な場合は、bool getMin = falseを渡します。
これにより、「データリーダーは指定されたものと互換性がありません」のEntity FrameWorkエラーが発生しています。
エラーの最も関連する部分
{"メッセージ": "エラーが発生しました。"、 "ExceptionMessage": "データリーダーは、指定された 'CatalogModel.proc_GetFramingSystems_Result'と互換性がありません。タイプ 'FrameType'のメンバーには、対応する列がありません同じ名前のデータリーダー。 "、" ExceptionType ":" System.Data.EntityCommandExecutionException "、
明らかに、エラーは、データリーダーがクエリ結果にないプロパティ 'FrameType'を設定しようとしたことを示しています。
今、私はエラーを理解しています、私が知りたいのは、このSQL sprocを2つのsprocに分割するつもりですか、またはこの回避策がありますか?
以下の私の機能
public static IEnumerable<IFramingSystem> GetFramingSystems(int brandID, string frameType, string glazeMethod, bool getMin)
{
using (CatalogEntities db = new CatalogEntities())
{
return db.proc_GetFramingSystems(brandID, frameType, glazeMethod, getMin).ToList<IFramingSystem>();
};
}
以下のMy TSQL
ALTER proc [Catelog].[proc_GetFramingSystems]
@BrandID INT,
@FrameType VARCHAR(26),
@GlazeMethod VARCHAR(7) ='Inside',
@getMin BIT = 0
as
BEGIN
SET NOCOUNT ON;
IF @getMin =0
BEGIN
SELECT c.ID,c.Name,c.Descr,c.FrameType,c.isSubFrame,
c.GlassThickness,c.GlassPosition,c.GlazingMethod,c.SillProfile
from Catelog.Component c
WHERE c.MyType ='Frame'
AND c.FrameType = @FrameType
AND c.GlazingMethod = @GlazeMethod
AND c.ID IN(
SELECT cp.ComponentID FROM Catelog.Part p JOIN
Catelog.ComponentPart cp ON p.ID = cp.PartID
WHERE p.BrandID = @BrandID
)
ORDER BY c.Name
END
ELSE
SELECT c.ID,c.Name,c.Descr
from Catelog.Component c
WHERE c.MyType ='Frame'
AND c.FrameType = @FrameType
AND c.GlazingMethod = @GlazeMethod
AND c.ID IN(
SELECT cp.ComponentID FROM Catelog.Part p JOIN
Catelog.ComponentPart cp ON p.ID = cp.PartID
WHERE p.BrandID = @BrandID
)
ORDER BY c.Name
SET NOCOUNT OFF;
END;
私には、IF
の両方のブランチが異なるデータを返し、最初のブランチは9列を返しますが、2番目は3列のみを返します。 EFは後者のIFramingSystem
を反映できないと思います。具体的には、列FrameType
(および他の5つの列)が明らかに欠落しています。
...
SELECT c.ID,c.Name,c.Descr <- where are the remaining columns
from Catelog.Component c
...
これは古い投稿であることを理解しています。しかし、私はこれについて今夜学んだことを共有したかった。 「エラーメッセージの最も関連性のある部分が述べている」ことがわかったのはこれです。
db.proc_GetFramingSystems(brandID, frameType, glazeMethod, getMin).ToList<IFramingSystem>();
エイリアスが「FrameType」のストアドプロシージャから列が返されることを期待しています。
プログラマにわかりやすい名前でテーブルのPOCO(単純な古いclrオブジェクト)クラスを作成したときに、これに遭遇しました。 「email_address」という厳密に入力された名前の代わりに、「EmailAddy」などが必要でした。他のマップされた列の中でこれを示すマップされたクラスを作成しました。
this.Property(t => t.EmailAddy).HasColumnName("email_address");
これはEFの他の部分が機能するために必要ですが、db.SqlQueryの実行時にマッピングクラスは参照されません。そのため、以下のコードを実行すると
var a = new SqlParameter("@fshipno", shipno);
return _context.db.SqlQuery<EmailList>("exec spGetEmailAddy @fshipno", a).ToList();
「FrameType」の代わりに「EmailAddy」に言及した以外は同じエラーを生成しました。修正...ストアドプロシージャの 'email_address'列を 'EmailAddy'にエイリアスして、返されたデータセットをPOCOにマップする必要がありました。
編集:これは、メソッドがIEnumberableを返している場合にのみ機能することがわかりました
public IEnumberable<myPOCO> GetMyPoco()
単一のPOCOオブジェクトを返そうとすると、同じエラーメッセージが表示されます。
public myPOCO GetMyPoco()
挿入/削除/更新(これらはEFによって「非クエリ」と見なされる)で、コードを使用して呼び出すことができる場合
_MyDbContext.Database.ExecuteSqlCommand(insert into Table (Col1,Col2) values (1,2));
_
ただし、生のSQLステートメントに対して選択クエリを実行している場合は、
_MyDbContext.DbSet<Table_name>.SqlQuery(select * from table_name).ToList();
_
または
_MyDbContext.Database.SqlQuery(select * from table_name).ToList();
_
()
EFのSqlQuery()
関数は、奇妙な理由で、例外の挿入/削除/更新操作をスローします。 (スローされる例外は「型のメンバーで、同じ名前のデータリーダーに対応する列がありません。」)しかし、Sql Management Studioを開いてエントリをチェックすると、実際に操作が実行されます。
参考までに http://www.entityframeworktutorial.net/EntityFramework4.3/raw-sql-query-in-entity-framework.aspx