【发布时间】:2018-12-08 11:20:43
【问题描述】:
我正在使用 Entity Framework 来查询由模型定义的数据库:在这个模型中,我有几个具有 #region dynamic values 的类:
[DataContract]
public class Job : AbstractEntity, IJob
{
[DataMember]
public virtual Guid Id { get; set; }
...
#region dynamic values
[DataMember]
public virtual string MetadataValue { get; set; }
[DataMember]
public virtual string ParametersValue { get; set; }
[DataMember]
public virtual string AttributesValue { get; set; }
#endregion
#region links
...
#endregion
}
AttributesValue、MetadataValue 和 ParametersValue 被声明为字符串,但作为 XML 文档存储在数据库中。我知道这与模型不一致,应该更改,但由于某些原因,它已以这种方式进行管理,我不允许对其进行修改。
为了更好地处理问题,我创建了一个单元测试,代码如下:
public class UnitTest1
{
private ModelContext mc;
[TestInitialize]
public void TestInit()
{
IModelContextFactory mfactory = ModelContextFactory.GetFactory();
mc = mfactory.CreateContextWithoutClientId();
}
[TestMethod]
public void TestMethod1()
{
DbSet<Job> jobs = mc.Job;
IQueryable<string> query = jobs
.Where(elem => elem.AttributesValue == "<coll><item><key>ids:ui:description</key><value>Session Test</value></item><item><key>ids:all:type</key><value>signature</value></item></coll>")
.Select(elem => elem.AttributesValue);
List<string> attrs = new List<string>(query);
foreach (string av in attrs)
{
Console.WriteLine(av ?? "null");
}
Assert.AreEqual(1, 1);
}
}
关于TestInit 和ModelContext 的简要说明:
ModelContext继承自DbContext,是SqlModelContext和OracleModelContext实现的抽象类(都覆盖OnModelCreating)。根据连接字符串,CreateContextWithoutClientId 返回SqlModelContext 或OracleModelContext。摘要:工厂模式。
让我们开始着手:TestMethod1。
这里的问题出在Where 方法中,返回的错误正如预期的那样:
SqlException: 数据类型 nvarchar 和 xml 在等于运算符中不兼容。
(从现在开始我只考虑AttributesValue 属性)
我想到了一些可能的解决方案,分别是:
在模型中创建一个新属性(但未映射到数据库)并将其用作“代理”,而不是直接访问
AttributesValue。但是在 Linq 中只能使用映射的属性,所以我放弃了它。直接对
IQueryable生成的内部 SQL 查询进行操作,并为 Oracle 和 Sql Server db 使用自定义的CAST。出于明显的原因,我宁愿避免这样做。
有没有办法指定一个自定义的属性获取器,以便我可以在访问之前将AttributesValue 转换为字符串?或者DbModelBuilder上的一些配置?
我正在使用标准实体框架 6,代码优先方法。
【问题讨论】:
-
它对我有什么帮助?但是,它不起作用,只是尝试了。还是谢谢。
-
EF6 还是 EF Core?如果是 EF6,代码优先模型还是 edmx?
-
@IvanStoev 我完全忘记指定了,谢谢。
标签: c# sql xml entity-framework linq