简体   繁体   English

如何在 Entity Framework Core 的复合键中配置与常量的关系?

[英]How to configure relationship with a constant in the composite key for Entity Framework Core?

public class Order
{
    public int Id { get; set; }
    public string Type { get; set; }
}

Order has the composite key (Id, Type) . Order具有复合键(Id, Type)

public class SalesOrderItem
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public Order Order { get; set; }
}

SalesOrderItem has the key Id . SalesOrderItem具有键Id

I want to configure a relation between SalesOrderItem and Order .我想配置SalesOrderItemOrder之间的关系。 SalesOrderItem does not have an OrderType column that can be used to create the composite key for the relation. SalesOrderItem没有可用于为关系创建复合键的OrderType列。 OrderType is always SAL when working with SalesOrderItem .使用SalesOrderItem时, OrderType始终为SAL

I have tried to configure the relation by setting a constant in the foreign key part:我试图通过在外键部分设置一个常量来配置关系:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<Order>()
        .HasKey(o => new { o.Id, o.Type });

    modelBuilder
        .Entity<SalesOrderItem>()
        .HasKey(s => s.Id);

    modelBuilder
        .Entity<Order>()
        .HasMany<SalesOrderItem>()
        .WithOne(salesOrderItem => salesOrderItem.Order)
        .HasForeignKey(salesOrderItem => new {salesOrderItem.OrderId, Type = "SAL"});
}

This does not work.不起作用

What can I do?我能做些什么?

You cannot use constant as a reference but instead you can derive another table like this:您不能使用常量作为参考,而是可以像这样导出另一个表:

public class SalesOrder : Order
{
}

public class SalesOrderItem
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public SalesOrder Order { get; set; }
}

and configure your salesorder like this并像这样配置您的销售订单

modelBuilder.Entity<Order>()
    .HasDiscriminator(t => t.Type)
    .HasValue<SalesOrder>("SAL");

then map with just foreign key to sales order然后 map 与销售订单的外键

modelBuilder
    .Entity<Order>()
    .HasMany<SalesOrderItem>()
    .WithOne(salesOrderItem => salesOrderItem.Order)
    .HasPrincipalKey(salesOrderItem => salesOrderItem.OrderId);

EDIT: Since it has composite index using principal key is the option as @Jogge commented.编辑:由于它具有使用主键的复合索引,因此@Jogge 评论道。

bit different view on the same problem.对同一个问题有点不同的看法。 (i am moving project from plain sqlrecord to ef core, so it is data first. and data structure can't be modified for now. so it is not optimal in many parts) (我正在将项目从普通 sqlrecord 移动到 ef core,所以它是数据优先。并且数据结构暂时无法修改。所以它在很多部分都不是最优的)

i have tasks, which may have few steps and each step may have a comment.我有任务,可能有几个步骤,每个步骤都可能有评论。 comments are stored in separate table.评论存储在单独的表中。 and other objects in database may have comments in the same table.和数据库中的其他对象可能在同一个表中有注释。 so the data structure is所以数据结构是

  public partial class Comment
    {
        public int Id { get; set; }
        public int RefType { get; set; }
        public int RefId { get; set; }
        public int? RefId1 { get; set; }
        public string Comment1 { get; set; }
    }

where RefType is referring object type其中 RefType 指的是 object 类型

Refid is id of referring object Refid 是引用 object 的 id

RefId1 is second id if needed如果需要,RefId1 是第二个 id

enities (partially)实体(部分)

public enum RefType : int { UNKNOWN = 0, TASK, TaskStep };
public partial class TaskHist
    {
        public int TaskId {get;set;}
        public ICollection<TaskStep> TaskSteps { get; set; }
    }

    public partial class TaskStep
    {
        public int Id { get; set; }
        public int TaskId { get; set; }
        public int StepNum { get; set; }
        public tsComment comment { get; set; }
    }

    // tsComment only for descriminator
    public class tsComment : Comment
    { 
    }

model configuration partially model 配置部分

   modelBuilder.Entity<Comment>(entity =>
            {
                entity.HasKey(c => c.Id);
                entity.HasDiscriminator<int>(c=>c.RefType)
                        .HasValue<Comment>(0)
                        .HasValue<tsComment>((int)RefType.TaskStep)
                        .IsComplete(false);

            });
   modelBuilder.Entity<TaskHist>(entity =>
            {
                entity.HasKey(t => t.TaskId);
                entity.HasMany(t=>t.TaskSteps).WithOne().HasForeignKey(t=>t.TaskId);
            });
   modelBuilder.Entity<TaskStep>(entity =>
            {
                entity.HasOne(t => t.comment).WithOne()
                      .HasForeignKey<TaskStep>(c=> new {c.TaskId, c.StepNum})
                      .HasPrincipalKey<tsComment>(c=> new {c.RefId, c.RefId1});
            });





声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM