一对多导航属性不起作用

时间:2018-01-25 18:19:27

标签: c# entity-framework-6 ef-code-first ef-fluent-api

所以我有两个表,用户和评论。 reviews表在users.user_key上有一个外键约束。我试图让ReviewModel中的导航属性用户填充。而另一种方式。我无法在UserModel中获取ICollection Reviews属性来填充。

的usermodel

public class UserModel
{
    public int UserKey { get; set; }  
    public virtual ICollection<ReviewModel> Reviews { get; set; }
}

UserConfiguration

class UserConfiguration : EntityTypeConfiguration<UserModel>
{
    public UserConfiguration()
    {
        this.ToTable("users", "sec");

        this.HasKey(k => k.UserKey);

        this.Property(p => p.UserKey)
            .IsRequired()
            .HasColumnName("user_key")
            .HasColumnType("int");

        this.HasMany(r => r.Reviews)
            .WithOptional()
            .HasForeignKey(k => k.UserKey);

        //this.HasOptional(r => r.Reviews)
        //    .WithMany()
        //    .HasForeignKey(k => k.UserKey);
    }
}

ReviewModel

public class ReviewModel
{
    public int ReviewKey { get; set; }
    public int UserKey { get; set; }

    public virtual UserModel User { get; set; }
}

ReviewConfiguration

public ReviewConfiguration()
{
    this.ToTable("reviews", "dbo");

    this.HasKey(k => k.ReviewKey);

    this.Property(p => p.ReviewKey)
        .HasColumnName("review_key")
        .HasColumnType("int")
        .IsRequired();

    this.Property(p => p.UserKey)
        .HasColumnName("user_key")
        .HasColumnType("int")
        .IsOptional();

    this.HasRequired(p => p.User)
        .WithMany(u => u.Reviews);

    //this.HasRequired(p => p.User)
    //    .WithRequiredPrincipal()
    //    .Map(m => m.ToTable("users", "sec").MapKey("user_key"));
}

我将配置类分开,并假设我在SQL数据库中正确设置了外键。这是我的DbContext类,我不断收到错误。

public class TestDbContext : DbContext
{
    public DbSet<ReviewModel> reviews { get; set; }
    public DbSet<UserModel> users { get; set; }

    public TestDbContext() : base("name=TestConnection")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new ReviewConfiguration());
        modelBuilder.Configurations.Add(new UserConfiguration());
    }

    public IEnumerable<ReviewModel> getReviews()
    {
        try
        {
            IEnumerable<ReviewModel> reviews = (from r in this.reviews
                                                     select r).DefaultIfEmpty();
            return reviews;
        }
        catch(SqlException ex)
        {
            throw ex;
        }
    }
}

每次运行此操作都会出现此错误。

  

在'NameSpace.Models.UserModel'类型上声明的导航属性'Reviews'已配置了冲突的多重性。

我使用this link作为参考,我甚至没有HasOne()或WithOne()的选项。

如果删除所有导航属性,我可以填充DbSets,这不是数据库连接问题。

所有注释掉的代码都是我试图让它工作的其他东西。

如果我在ReviewConfiguration中注释掉第一个.HasRequired并取消注释另一个,我会收到此错误。

  

在模型生成期间检测到一个或多个验证错误:

     

user_key:名称:类型中的每个属性名称必须是唯一的。已定义属性名称“user_key”。“

所以问题是有没有人知道如何为表A设置DbContext配置,表A中有一个外键,表A可以有多个键与表B中的单个键相关联,而表B没有有任何外键。

更新 根据莱昂纳多的建议,我将配置更改为......

UserConfiguration:

class UserConfiguration : EntityTypeConfiguration<UserModel>
{
    public UserConfiguration()
    {
        this.ToTable("users", "sec");

        this.HasKey(k => k.UserKey);

        this.Property(p => p.UserKey)
            .IsRequired()
            .HasColumnName("user_key")
            .HasColumnType("int");

        this.HasMany(r => r.Reviews)
            .WithRequired(u => u.User)
            .HasForeignKey(k => k.UserKey);
    }
}

ReviewConfiguration

public class ReviewConfiguration : EntityTypeConfiguration<ReviewModel>
{
    public ReviewConfiguration()
    {
        this.ToTable("trail_reviews", "dbo");

        this.HasKey(k => k.ReviewKey);

        this.Property(p => p.ReviewKey)
            .HasColumnName("review_key")
            .HasColumnType("int")
            .IsRequired();

        this.Property(p => p.UserKey)
            .HasColumnName("user_key")
            .HasColumnType("int")
            .IsRequired();

        this.HasRequired(p => p.User)
            .WithMany(u => u.Reviews)
            .HasForeignKey(k => k.UserKey);
    }
}

现在构建了ReviewModel集合,但从不填充User属性。我在数据库中检查了每个表中正确的user_key,数据是否正确。我还在ReviewConfiguration上添加了.HasForeignKey(),但无论是否使用它,都不会填充User属性。

生成的SQL查询也看起来不正确。它看起来像是外部加入评论表本身???

SELECT 
    [Project1].[review_key] AS [review_key], 
    [Project1].[user_key] AS [user_key]
    FROM   ( SELECT 1 AS X ) AS [SingleRowTable1]
    LEFT OUTER JOIN  (SELECT 
        [Extent1].[review_key] AS [review_key], 
        [Extent1].[user_key] AS [user_key]
        FROM [dbo].[reviews] AS [Extent1]) AS [Project1] ON 1 = 1

*******更新2 ******** 好吧,我在IEnumerable上放了一个.ToList(),我正在返回,并且填充了User属性。当我将它传回视图时,它会以某种方式丢失,因为当我在剃刀视图中放置断点时,User属性是一个错误。因此,我将莱昂纳多的答案标记为正确,因为他解决了配置问题。

1 个答案:

答案 0 :(得分:1)

您需要进行审核     this.HasRequired(p =&gt; p.User)             .WithMany(u =&gt; u.Reviews);

这意味着..审核时需要用户。

对于您有

的用户
this.HasMany(r => r.Reviews)
        .WithOptional()
        .HasForeignKey(k => k.UserKey);

这意味着..用户在审核中是可选的。

更改

this.HasMany(r => r.Reviews)
        .WithOptional()
        .HasForeignKey(k => k.UserKey);

this.HasMany(r => r.Reviews)
        .WithRequired(t=> t.UserModel)
        .HasForeignKey(k => k.UserKey);

请注意所需的用户模型

 this.Property(p => p.UserKey)
        .HasColumnName("user_key")
        .HasColumnType("int")
        .IsOptional();

 this.Property(p => p.UserKey)
        .HasColumnName("user_key")
        .HasColumnType("int")
        .IsRequired();