Средство чтения данных несовместимо с указанной 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