【发布时间】:2018-02-06 15:07:50
【问题描述】:
我正在尝试通过查询 XML 列来使用实体框架检索一些实体。实体框架不支持这个,所以我不得不使用原始 SQL。
var people = context.People.SqlQuery("SELECT * FROM [People] WHERE [DataXML].value('Properties/Age', 'int') = 21").AsQueryable().AsNoTracking();
我的人物类:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
[Column("YearsSinceBirth")]
public int Age { get; set; }
[Column(TypeName = "xml")]
public string DataXML { get; set; }
}
这应该可以,但是在尝试将其映射回对象时它会失败。具体来说,它落在 Age 属性上,该属性的列名被覆盖为“YearsSinceBirth”。
'数据读取器与指定的不兼容 'MyProject.CodeBase.DataModel.DbEntities.Person'。的成员 类型“年龄”在数据读取器中没有对应的列 同名。'
我猜测 Entity Framework 不会将数据库列名称映射到对象属性名称,因此希望该列被命名为“Age”而不是“YearsSinceBirth”。
我不想在 SQL 查询(如SELECT YearsSinceBirth As Age)中列出每一列及其映射,因为我正在处理的实际项目中,该列有更多列,这意味着每次架构更改时查询都会中断(有点违背实体框架的目的)。
【问题讨论】:
-
恐怕您将不得不指定列名,或者创建另一个与您要使用的名称匹配的类。
-
因为你在做
context.People.SqlQuery("Select *....")EF 很可能没有使用属性,我相信如果你像context.People.Where(p => p.DataXml ....)那样查询的话会使用属性 -
@VidmantasBlazevicius 是的,不幸的是我不能,因为实体框架不支持在数据库上查询 XML
-
@KeirNellyer 是否有任何选项可以编写存储过程或函数来封装它?
-
如果我确实需要声明列名,是否有动态生成它们?我觉得使用反射和检查 [Column] 属性有点太简单了,如果没有定义映射,EF 有时会使用带有下划线的列名。
标签: c# sql-server entity-framework