Средство чтения данных несовместимо с указанной Entity Framework
у меня есть метод, который вернет голые минимальные результаты из sproc для заполнения меню выбора. Когда мне нужны голые результаты min, я передаю bool getMin = true в sproc, а когда мне нужна полная запись, я передаю bool getMin = false.
это вызывает ошибку Entity FrameWork "считыватель данных несовместим с указанным"
наиболее релевантная часть ошибки
{"сообщение":"Ошибка произошло.", "ExceptionMessage": "устройство чтения данных несовместимо с указанной моделью каталога.proc_GetFramingSystems_Result'. Член типа "FrameType" не имеет соответствующего столбца в считывателе данных с тем же именем.", "ExceptionType": "System.Данные.EntityCommandExecutionException",
очевидно, ошибка говорит мне, что, когда устройство чтения данных попыталось установить свойство "FrameType", которого нет в результатах запроса.
Теперь Я поймите ошибку, я хочу знать, что я собираюсь разделить этот sql sproc на два sprocs или для этого есть работа?
моя функция ниже
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>();
};
}
мой 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;
3 ответов
мне кажется, что обе ветви IF
возвращает разные данные, первая ветвь возвращает 9 столбцов, где вторая - только три. Я считаю, что 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) моей таблицы с более дружественными программисту именами. Вместо строго напечатанного имени say "email_address", я хотел "EmailAddy" и так далее. Я создал сопоставленный класс, указав это среди других сопоставленных столбцов.
this.Property(t => t.EmailAddy).HasColumnName("email_address");
хотя это необходимо для работы других частей EF, класс сопоставления не ссылается при выполнении БД.SQL-запрос. Итак, когда приведенный ниже код выполняет
var a = new SqlParameter("@fshipno", shipno);
return _context.db.SqlQuery<EmailList>("exec spGetEmailAddy @fshipno", a).ToList();
он сгенерировал ту же ошибку, за исключением того, что вместо "FrameType" он упомянул "EmailAddy". Затруднительное положение... Мне пришлось псевдоним столбца "email_address" в моей хранимой процедуре, чтобы 'EmailAddy', чтобы получить его для сопоставления возвращенного набора данных с моим POCO.
EDIT: я обнаружил, что это работает, только если ваш метод возвращает IEnumberable
public IEnumberable<myPOCO> GetMyPoco()
вы получите то же сообщение об ошибке, если вы пытаетесь вернуть один объект POCO.
public myPOCO GetMyPoco()
если вы вставляете / удаляете / обновляете (они рассматриваются EF как "не-запрос") и могут быть вызваны нашим кодом с помощью
MyDbContext.Database.ExecuteSqlCommand(insert into Table (Col1,Col2) values (1,2));
но если вы делаете запрос select для инструкции raw SQL, используйте
MyDbContext.DbSet<Table_name>.SqlQuery(select * from table_name).ToList();
или
MyDbContext.Database.SqlQuery(select * from table_name).ToList();
()
на SqlQuery()
функция, в EF, по странным причинам, бросьте операцию вставки/удаления/обновления исключения. (Возникает исключение "член типа, не имеет соответствующего столбца в данных читатель с таким же именем.") Но он фактически выполнил операцию, если вы откроете свою среду SQL Management Studio и проверите записи.
FYI http://www.entityframeworktutorial.net/EntityFramework4.3/raw-sql-query-in-entity-framework.aspx