使用Entity Framework 6.0,Fluent API和DataAnnotations重新使用所需属性的列 [英] Reusing a column for a required property with Entity Framework 6.0, Fluent API, and DataAnnotations

查看:138
本文介绍了使用Entity Framework 6.0,Fluent API和DataAnnotations重新使用所需属性的列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基类

  public class BaseClass 
{
public int Id {get; set;}
}

和两个派生类

  public class Foobar:BaseClass 
{
[必需]
public int无论{get; set;}
}

public class Snafu:BaseClass
{
[必需]
public int Whatever {get; set;}
}

我正在使用Table Per Hierarchy继承并试图减少在我的重复列上,所以使用Fluent API,我已经如此映射了他们:

  modelBuilder.Entity< Foobar>()。属性(fb => fb.Whatever).HasColumnName(Whatever); 
modelBuilder.Entity< Snafu>()。Property(sf => sf.Whatever).HasColumnName(Whatever);

但是,这会导致


(137,10):错误3023:映射从第137行开始的片段中的问题:Column BaseClass.BatClass必须映射的任何内容:它没有默认值,不可为空。


在EF6中,如果我取消 [Required] 属性,这种类型的映射似乎工作正常从两个子类。在两个派生类中添加一个 [DefaultValue(0)] 属性无法解决问题。



任何想法如何获取这些属性在数据库中共享列,同时维护其所需的属性?

解决方案

这实际上是EF6中的一个错误。在EF5中,所使用的场景根本不起作用(我们将抛出列名称必须是唯一的异常)。在EF6中,我们做了一些工作来实现它,但显然我们错过了事实,即即使在派生类型中需要属性,数据库中的共享列也必须是空的。后者是因为除非基类是抽象的,否则您需要能够存储基类型的实例,并且对于基类型的任何实例,列应为空。



https://entityframework.codeplex.com/workitem/1924



随意投票。



对于解决方法,如果具有中介类型不是一个选项,您可以将列标记为可空,明确地在实体配置上附加对.IsOptional()的调用。这不会给你准确的想要的,因为EF数据验证的目的是对流畅的API上的IsOptional()的调用将覆盖[必需]数据注释。然而,其他的数据验证方式,如MVC的验证,仍然会符合这个属性。



还有其他可能的解决方法,我还没有尝试,也许如果可以接受使用TPT并且有两种派生类型都有不同的生活在不同的表,这将工作。我相信任何依赖于设置默认值的方法都不会有帮助,因为错误不仅仅是表模式不能容纳基类的实例,而且也是由Code First生成的EF映射不是



更新:这将在实体框架版本6.1.0中得到修正,该版本目前可用于测试版。


I have a base class

public class BaseClass
{
    public int Id {get; set;}
}

and two derived classes

public class Foobar: BaseClass
{
    [Required]
    public int Whatever {get; set;}
}

public class Snafu: BaseClass
{
    [Required]
    public int Whatever {get; set;}
}

I'm using Table Per Hierarchy inheritance and trying to cut down on my duplicate columns, so with Fluent API I've mapped them like so:

        modelBuilder.Entity<Foobar>().Property(fb => fb.Whatever).HasColumnName("Whatever");
        modelBuilder.Entity<Snafu>().Property(sf => sf.Whatever).HasColumnName("Whatever");

However, this results in

(137,10) : error 3023: Problem in mapping fragments starting at line 137:Column BaseClass.Whatever in table BaseClass must be mapped: It has no default value and is not nullable.

In EF6 this type of mapping seems to work fine if I take off the [Required] attribute from both subclasses. Adding a [DefaultValue(0)] attribute to both derived classes does not fix the problem.

Any idea how to get these properties to share a column in the database while maintaining their required attribute?

解决方案

This is actually a bug in EF6. In EF5 the scenario used not to work at all (we would throw an exception in the lines of "column names need to be unique"). While in EF6 we did some work to enable it, but apparently we missed the fact that the shared column has to be nullable in the database even if the property is required in the derived types. The latter is because unless the base class is abstract, you need to be able to store an instance of the base type and for any instance of the base type the column should be null.

I have filed the issue in our bug database:

https://entityframework.codeplex.com/workitem/1924

Feel free to vote for it.

As for a workaround, if having an intermediary type is not an option, you can mark the column as nullable explicitly appending a call to .IsOptional() on the entity configurations. This won't give you exactly what you want because for the purpose of EF data validation this call to IsOptional() on the fluent API will override the [Required] data annotation. However, other flavors of data validation, such as MVC's validation will still honor the attribute.

There are other possible workarounds that I haven't tried, maybe if it is acceptable to use TPT and have both derived types have Whatever live in a different table this would work. I believe any approach that relies on setting a default value won't help because the bug is not only about the table schema not being able to hold an instance of the base class, it is also about the EF mapping generated by Code First not being valid.

UPDATE: This will be fixed in Entity Framework version 6.1.0 which is currently available in beta.

这篇关于使用Entity Framework 6.0,Fluent API和DataAnnotations重新使用所需属性的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆