繁体   English   中英

EntityFrameworkCore-将DbSet筛选为另一个实体上的单个属性

[英]EntityFrameworkCore - Filter DbSet to a single property on another Entity

我有一个Account实体,在该实体上我想要一个名为CurrentSubscriptionSubscription属性。

public class Account
{
    public int Id { get; set; }
    public Subscription CurrentSubscription { get; set; }
}

public class Subscription
{
    public int Id { get; set; }
    public int AccountId { get; set; }
    public Account Account { get; set; }
    public DateTime Start { get; set; }
    public DateTime? End { get; set; }
}

实际上,一个给定帐户可能有多个“ Subscription行,但是业务规则规定, EndDatenull (该Account的当前订阅)的情况下,将永远只有一个(或没有)。 在我的模型中,当我检索一个帐户时,我不在乎其他帐户,因为我只是在当前帐户之后。

我怎样才能告诉EF做到这一点? 玩弄流畅的API并不意味着PropertyBuilder上内置了任何东西, HasDefaultValueSql我发现的每个HasDefaultValueSql示例都具有琐碎的Sql类的"GETDATE()" ,而不是参数化的东西,而这需要在( ..where AccountId = ? )。

所以我被卡住了..有什么想法吗?

这应该在您的情况下有效:

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

    //Collection automatically loaded by EF
    public virtual List<Subscription> Subscriptions { get; set; }

    // Returns Only (or none) subscription with null End date 
    public Subscription CurrentSubscription => Subscriptions.SingleOrDefault(r=>r.End == null);
}

如果在Subscription类(或Fluent API)上正确设置了外键,则由Entity Framework自动(延迟)加载Account.Subscriptions -collection:

public class Subscription
{
    public int Id { get; set; }
    public int AccountId { get; set; }
    [ForeignKey("AccountId")]
    public Account Account { get; set; }
    public DateTime Start { get; set; }
    public DateTime? End { get; set; }
}

实际上,一个给定帐户可能有多个“订阅”行,但是业务规则规定,EndDate为null(该帐户的当前订阅)的情况下将永远只有一个(或没有)。 在我的模型中,当我检索一个帐户时,我不在乎其他帐户,因为我只是在当前帐户之后。 我怎样才能告诉EF做到这一点?

Entity Framework Core具有您要搜索的确切解决方案,即EF Core Relationships:一对一

因此,您的Subscription实体配置应如下所示:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Entity<Subscription>().HasOne(s => s.Account)
            .WithOne(a => a.CurrentSubscription).HasForeignKey<Subscription>(s => s.AccountId);
}

此外,由于Account将有一个或零个Subscription ,因此我们可以从Subscription实体中删除Id列,并使AccountId作为Subscription实体的主键,如下所示:

public class Subscription
{
    public int AccountId { get; set; }
    public Account Account { get; set; }
    public DateTime Start { get; set; }
    public DateTime? End { get; set; }
}

然后,您的Subscription实体配置应如下所示:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
     base.OnModelCreating(modelBuilder);

     modelBuilder.Entity<Subscription>(s =>
     {
        s.HasKey(sc => sc.AccountId); // <-- AccountId as primary key
        s.HasOne(sc => sc.Account).WithOne(a => a.CurrentSubscription)
                .HasForeignKey<Subscription>(sc => sc.AccountId);
     });
}

暂无
暂无

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

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