如何定义外键关系可选在FluentAPI /数据注释实体框架? [英] How do I define Foreign Key Optional Relationships in FluentAPI/Data Annotations with the Entity Framework?

查看:141
本文介绍了如何定义外键关系可选在FluentAPI /数据注释实体框架?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的代码(样品)应用程序:

I have a (sample) application with the following code:

public class Posts
{

    [Key]
    [Required]
    public int ID { get; set; }

    [Required]
    public string TypeOfPost { get; set; }

    public int PollID { get; set; }
    public virtual Poll Poll { get; set; }

    public int PostID { get; set; }
    public virtual Post Post { get; set; }

}



基本上,我不知道是否有一个这样做的更好的办法,但是,我的职位名单,而且,人们可以选择,如果它是一个民意测验发表,由于实体框架不枚举工作,我只是把它存储在 TypeOfPost ,然后在应用程序中,我以编程方式查询要么投票或发表根据 TypeOfPost 的值。

Basically, I don't know if there is a better way of doing this, but, I have a list of Posts, and, people can choose if it is a Poll or a Post, As Entity Framework doesn't work with Enums, I just store it as a string in TypeOfPost and then in the application, I programmatically query either Poll or Post based on the value of TypeOfPost.

我不认为这是无论如何设定的只需要一或类似的,所以,我处理应用程序中所有的检查和东西。 (如果有人知道一个更好的办法,请说!)。

I don't think there is anyway of setting "Only one required" or similar, so, I handle all the checking and stuff in the application. (If anyone knows a better way, please say!).

总之,问题是,我可以去到SQL Management Studio并手动编辑得到这个工作的罚款该架构允许空值 - 但是,我只是不知道如何在FluentAPI做到这一点,需要一些帮助。

Anyway, the problem is, I can get this working fine by going in to SQL Management Studio and manually editing the schema to allow nulls - but, I just can't work out how to do this in the FluentAPI, and need some help.

我曾尝试两项操作

        modelBuilder.Entity<Post>()
            .HasOptional(x => x.Poll).WithOptionalDependent();

        modelBuilder.Entity<Post>()
            .HasOptional(x => x.Poll).WithOptionalPrincipal();



第一个似乎创建在允许空值的数据库中的附加列中,而第二个没有按'吨似乎做任何事情。

The first one seems to create an additional column in the database that allows nulls, and the second one doesn't appear to do anything.

我认为第一个是我需要的,但是,我需要结合[ForeignKey的]在<$使用C $ C>发表类。如果我是正确的在这里,如果[ForeignKey的]走在虚拟财产或财产的ID?

I believe the first one is the one I need, but, I need to use it in combination with [ForeignKey] in the Post Class. If I am correct here, Should the [ForeignKey] go on the virtual property, or the ID of the property?

此外,什么是<$之间的实际差异C $ C> WithOptionalDependent 和 WithOptionalPrincipal ? - 我已阅读MSDN上,可是,我真的不明白的区别

In addition, what is the actual difference between WithOptionalDependent and WithOptionalPrincipal? - I have read on MSDN, but, I really do not understand the difference.

推荐答案

我可能会尝试创建两个要求,因为民意测验必须的有参考可选一比一的关系>帖子和发表也的必须的有参考帖子

I would probably try to create the two one-to-one relationships as optional:required because a Poll must have a reference to Posts and a Post also must have a reference to Posts:

modelBuilder.Entity<Posts>()
    .HasOptional(x => x.Post)
    .WithRequired();

modelBuilder.Entity<Posts>()
    .HasOptional(x => x.Poll)
    .WithRequired();

这使得帖子自动在主关系和发表民意测验依赖。校长有关系的主键,依赖外键这也同时在发表 / 民意测验<主键/ code>表,因为它是一个一对一的关系。只有在一个一对多的关系,你就必须为外键一个单独的列。对于一对一的关系,你也必须删除外键列帖子ID PollId ,因为帖子是指通过其主键的发表民意测验

This makes Posts automatically the principal in the relationship and Post or Poll the dependent. The principal has the primary key in the relationship, the dependent the foreign key which is also the primary key at the same time in Post/Poll table because it is a one-to-one relationship. Only in a one-to-many relationship you would have a separate column for the foreign key. For a one-to-one relationship you also have to remove the foreign key columns PostId and PollId because Posts refers through its primary key to the Post and Poll.

这似乎是在模型中相应的另一种方法是继承映射。然后,该模型是这样的:

An alternative approach which seems to be appropriate in your model is inheritance mapping. Then the model would look like this:

public abstract class BasePost  // your former Posts class
{
    public int ID { get; set; }
    public string UserName { get; set; }
}

public class Post : BasePost
{
    public string Text { get; set; }
    // other properties of the Post class
}

public class Poll : BasePost
{
    // properties of the Poll class
}

您不需要 TypeOfPost 然后了,因为你可以使用 OfType LINQ运营商过滤两个具体类型,例如:

You don't need the TypeOfPost then anymore because you can filter the two concrete types using the OfType LINQ operator, for example:

var x = context.BasePosts.OfType<Post>()
    .Where(p => p.UserName == "Jim")
    .ToList();

这将选择特定用户的所有职位,但不投票。

This would select all posts of a particular user but not the polls.

您必须决定,那么你要使用哪一种继承映射 - 的 TPH,TPT或TPC

You have to decide then which kind of inheritance mapping you want to use - TPH, TPT or TPC.

修改

要得到你可以指定流利的API以下映射一个一对多的关系:

To get a one-to-many relationship you can specify the following mapping in Fluent API:

modelBuilder.Entity<Posts>()
    .HasOptional(x => x.Post)
    .WithMany()
    .HasForeignKey(x => x.PostID);

modelBuilder.Entity<Posts>()
    .HasOptional(x => x.Poll)
    .WithMany()
    .HasForeignKey(x => x.PollID);



外键的属性必须是可空( INT?),这是你已经找到。因为你的外键属性的命名遵循命名约定EF用来映射你可以完全忽略流利的映射。如果您有非常规的名字(例如 PostFK 或某事),这只会是必需的。然后,您可以同时使用数据的注释( [ForeignKey的(...)] 属性),而不是流利的API。

The foreign key properties must be nullable (int?) for this as you already found. Because the naming of your foreign key properties follows the naming convention EF uses for mapping you can omit the Fluent mapping altogether. It would only be required if you had unconventional names (like PostFK or something). You could then also use data annotations ([ForeignKey(...)] attribute) instead of Fluent API.

这篇关于如何定义外键关系可选在FluentAPI /数据注释实体框架?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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