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

时间:2016-05-18 14:42:47

标签: c# entity-framework generics interface coded-ui-tests

我遇到一个问题,其中Coded UI项目在数据访问上抛出了ModelValidationException,但其他项目(Unit Tests,Web,Console,WinForm)却没有。

我的底层数据库有几组Code-First实体,它们具有不同状态的类似属性。粗略地,想一个报价和销售记录。由于我无法控制或输入的原因,这些记录根据业务事务的状态分为不同的表。

所以我有一组具有共同字段和一些重复的实体:

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.
}

由于这种共性,我有一组实现映射到Entity Framework类的类,使用泛型和接口来实现公共元素。我有这些接口也使用泛型来强制类型完整性,所以Quote不能有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种泛型类型。所有生产和测试代码都很好。一切正常,直到我开始编写Coded 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项目中,而不是任何其他项目类型。

Coded用户界面和实体框架之间是否存在已知冲突?

编辑:在堆栈跟踪中添加了小文本更正

2 个答案:

答案 0 :(得分:0)

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

它至少显然是你在系统中放入的数据,而不是编码用户界面。 我们可以在您的代码段中看到字符串长度错误和重复错误。

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

答案 1 :(得分:0)

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

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

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

我承认我在EF中生锈了,但我不确定的是你如何插入这些记录而没有按照你在评论中的建议进行验证。