编码的UI项目导致实体框架ModelValidationException



我遇到一个问题,编码的UI项目在数据访问时抛出ModelValidationException,但其他项目(单元测试、Web、控制台、WinForm)没有。

我的底层数据库有几组"代码优先"实体,它们对于不同的状态具有相似的属性。大致来说,想想报价和销售记录。由于我无法控制或输入的原因,这些记录根据业务事务的状态被拆分为不同的表。

因此,我有一组具有公共字段和一些重复的实体:

public class QuoteMoney
{
     Decimal Amount { get; set; }
     //...etc.
}
public class SaleMoney
{
     Decimal Amount { get; set; }
     //...etc.
}
public class Quote
{
    List<QuoteMoney> QuoteMonies { get; set; }
     //...etc.
}
public class Sale
{
    List<SaleMoney> SaleMonies { get; set; }
     //...etc.
}

由于通用性,我有一组实现映射到实体框架类的类,使用通用元素的泛型和接口。我有这些接口也使用泛型来强制类型完整性,这样报价就不能有SaleMoney等等。即:

public Interface IContainer<GContainer, GMoney>
    where GContainer : IContainer<GContainer, GMoney>
    where GMoney : IMoney<GContainer, GMoney>
{
    List<GMoney> Monies { get; set; }
}
public Interface IMoney<GContainer, GMoney>
    where GContainer : IContainer<GContainer, GMoney>
    where GMoney : IMoney<GContainer, GMoney>
{
     Decimal Amount { get; set; }
}

请注意,为了在接口上保留通用名称,结果有一个通用名称,但表有特定的集合名称。我们有我不想影响的现有代码,所以解决方案变成:

public class QuoteMoney : IMoney<Quote, QuoteMoney>
{
     Decimal Amount { get; set; }
     [NotMapped]
     Decimal IMoney<Quote, QuoteMoney>.Amount { get; set; }
     //...etc.
}
public class SaleMoney : IMoney<Sale, SaleMoney>
{
     Decimal Amount { get; set; }
     [NotMapped]
     Decimal IMoney<Sale, SaleMoney>.Amount { get; set; }
     //...etc.
}
public class Quote : IContainer<Quote, QuoteMoney>
{
    List<QuoteMoney> QuoteMonies { get; set; }
     [NotMapped]
     List<QuoteMoney> IContainer<Quote, QuoteMoney>.Monies { get; set; }
     //...etc.
}
public class Sale : IContainer<Sale, SaleMoney>
{
    List<SaleMoney> SaleMonies { get; set; }
     [NotMapped]
     List<SaleMoney> IContainer<Sale, SaleMoney>.Monies { get; set; }
     //...etc.
}

这个模式扩展到几个不同的集合,大约有7个泛型类型。这在所有的生产和测试代码中都很好。一切正常,直到我开始编写编码UI测试。我想插入一个伪记录,然后删除它并测试它是否有效。

当我尝试在编码的UI测试中进行插入(插入记录,旋转应用程序,然后删除)时,我会得到一个ModelValidationException,整个模型中的每个接口属性都有两个错误(为简洁起见,进行了编辑):

[Long Namespace].IQuote<[Long Namespace].Quote, [Long Namespace].QuoteMoney>, etc.>.Monies : Name: The specified name must not be longer than 480 characters: '[repeated name]'
[Long Namespace].IQuote<[Long Namespace].Quote, [Long Namespace].QuoteMoney>, etc.>.Monies : Name: The specified name is not allowed: '[repeated name]'

内部调用堆栈为:

at System.Data.Entity.Core.Metadata.Edm.EdmModel.Validate()
at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.InternalContext.Initialize()
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
at System.Linq.Queryable.First[TSource](IQueryable`1 source)

对于从整个模型中的泛型接口继承的每个类型上的每个类型的属性,这种情况都会重复出现。这只发生在编码的UI项目中,而不会发生在任何其他项目类型中。

编码UI和实体框架之间是否存在已知的冲突?

EDIT:添加在堆栈跟踪中,次要文本更正

Coded UI是一个自动的黑盒测试工具,它在客户端浏览器中工作,与服务器端的EF无关。

这是你放在系统中的数据,而不是编码的UI,至少表面上是这样。我们可以在您的代码片段中看到,存在字符串长度错误和重复错误。

请尝试减少通过CUI提供的字符串的长度,看看它是否有帮助。

Erik,正如Naeem所说,CodedUI是一种黑盒解决方案。我想我在很高的层次上理解你想要做的事情-将一条记录插入数据库,确保它通过CodedUI出现在应用程序的UI中,然后删除它。据我所知,我没有遇到任何特定于CodedUI的EF不兼容或褶皱。

我的直觉是,你会注意到你的单元测试项目和CodedUI项目之间的区别。也许在参考文献中。

另一个建议是让CodedUI项目调用另一个项目中存在的数据设置方法。理想情况下,您的服务/单元测试可能需要类似的数据设置。

我承认我对EF有些生疏,但我不确定的是,正如你在评论中建议的那样,你是如何在没有验证的情况下插入这些记录的。

最新更新