我有一个Account
实体,我想在其上拥有一个名为Subscription
的{{1}}属性。
CurrentSubscription
实际上,一个给定帐户可能有多个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
为EndDate
的行将永远只有一个(或没有)( null
的当前订阅)。在我的模型中,我在提取帐户时并不关心其他帐户,因为我只是在当前一个帐户之后。
如何告诉EF这样做?使用流畅的API并不意味着Account
上内置了任何内容,而且我发现的每个PropertyBuilder
示例都像HasDefaultValueSql
一样琐碎的Sql
,而不是某些东西参数化,这将是("GETDATE()"
)。
所以我被卡住了..有什么想法吗?
答案 0 :(得分:0)
这应该适合您的情况:
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)正确设置了外键,那么 Account.Subscriptions
-集合将由Entity Framework自动(延迟)加载:
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; }
}
答案 1 :(得分:0)
In reality, there could be multiple Subscription rows for a given account but a business rule dictates that there will only ever be one (or none) with an EndDate of null (the Account's current subscription). In my model I do not care about the others when I am retrieving an account as I am only after the current one. How can I tell EF to do this?
Entity Framework Core has exact solution that you are searching for and that is EF Core Relationships : One-to-One.
So your Subscription
entity configuration should be as follows:
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);
}
Moreover as there will be one or zero Subscription
for Account
so we can remove Id
column from Subscription
entity and make the AccountId
as the primary key of the Subscription
entity as follows:
public class Subscription
{
public int AccountId { get; set; }
public Account Account { get; set; }
public DateTime Start { get; set; }
public DateTime? End { get; set; }
}
Then your Subscription
entity configuration should be as follows:
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);
});
}