我有这样的DbModel配置:
modelBuilder.Entity<WishlistLine>()
.HasKey(w => w.PersistenceKey)
.Property(w => w.PersistenceKey)
.HasColumnName("WishlistLineId");
我通过以下两种方法运行查询:
public IEnumerable<WishlistLine> FetchWishlistLinesUsingLogonName(string logonName)
{
return GetFromRawSql(@"
SELECT wl.* FROM WishlistLines wl
INNER JOIN Accounts a ON wl.AccountId = a.AccountId
LEFT JOIN Users u ON u.AccountId = a.AccountId
WHERE u.LogonName = @p0", logonName);
}
protected IEnumerable<TEntity> GetFromRawSql(string sqlQuery, params object[] parameters)
{
return _dbSet.SqlQuery(sqlQuery, parameters).ToList();
}
我可以通过EF将WishlistLines“保存”到数据库中,没有任何问题.当我运行此查询但我收到此错误:
数据读取器与指定的“DataAccessLayer.DatabaseContext.WishlistLine”不兼容.类型为“PersistenceKey”的成员在数据读取器中没有相应的具有相同名称的列.
我知道使用DbSet< T> .SqlQuery()会将返回的数据映射到实体,但它似乎忽略了DbModel配置.从错误消息中判断(猜测)正在使用错误的数据读取器.
所以:
A)我做错了吗?
B)有没有办法利用EF的DbModel感知实体映射器?
最佳答案 实际上,在执行原始SQL查询时,将忽略列名映射.以下是两个参考文献:
This非常不满意的帖子只是为了好玩,但以下一个来自EF团队的认真回答:
引自http://entityframework.codeplex.com/workitem/233:
The SqlQuery method is designed not to take any mapping into account,
including mapping that is applied using attributes. It simply matches
the column names from the results with property names in the object.
If the column names don’t match you will need to use a column alias
(AS keyword in SQL Server) to rename the column in the results.We agree that it would be useful to have the option to make SqlQuery
honor Column attributes so we’re keeping this issue open and putting
it on our backlog for future consideration.
因此,唯一的解决方法似乎是在SQL查询中使用显式AS别名而不是*,将您的属性名称指定为列别名:
return GetFromRawSql(@"
SELECT wl.WishlistLineId AS PersistenceKey,
wl.SomeOtherColumn AS SomeOtherProperty,
...
..."
// ...