我有一个我想在数据库中表示的共享类型。我需要先知道代码是否可行,或者设计是否糟糕。 (请指出你的推理来源)。
这是布局:
public class A
{
public Guid Id;
public Guid ParentId; // Points to either B or C
public string Foo;
}
public class B
{
public Guid Id;
public virtual ICollection<A> ManyA { get; set; }
// Other fields
}
public class C
{
public Guid Id;
public virtual ICollection<A> ManyA { get; set; }
// Other fields
}
我使用[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
注释管理了GUID PK,我相信这会使这成为可能。
目标是保持A
- 表简单;我希望不要有B_Id
和C_Id
列,因为我认为它们是不必要的,并且将来可能会有D
类型有很多{ {1}} 就像A
和B
一样。此外,此方案还用于其他一些关系。
我认为问题的精神是显而易见的,但EF特定的班级成员只是为了说明。如果他们需要改变,那就这样吧。
(我为这个人为的例子感到抱歉,但是,揭露其真实性质,IMO并没有澄清问题)。
另外,我试着搜索几个小时!我不知道找到合适答案的正确命名法。我对数据库和EF一般都很陌生。
答案 0 :(得分:0)
不要使用Guid制作索引,为什么选择硬道路? :S
使用DataAnnotations,例如:
一堂课:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Web.Mvc;
namespace app.Models
{
[Table("A")]
public class A
{
[Key]
public int AId { get; set; }
[Required(ErrorMessage = "Campo obrigatório")]
[DisplayName("Title")]
[StringLength(100)]
public string Title { get; set; }
public virtual ICollection<B> bCollection { get; set; }
}
}
B班:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Web.Mvc;
namespace app.Models
{
[Table("B")]
public class B
{
[ScaffoldColumn(false)]
[Key]
public int BId { get; set; }
[DisplayName("Description")]
[StringLength(100)]
public string Description { get; set; }
public virtual ICollection<A> AList{ get; set; }
}
}
答案 1 :(得分:0)
我发现我可以为B
和C
类型创建一个公共基类型。例如:
class Program
{
static void Main(string[] args)
{
using (var context = new Ctx())
{
var b = new B();
var c = new C();
b.ManyA.Add(new A());
c.ManyA.Add(new A());
context.Cs.Add(c);
context.Bs.Add(b);
context.SaveChanges();
}
}
}
public class Ctx : DbContext
{
public DbSet<A> As { get; set; }
public DbSet<B> Bs { get; set; }
public DbSet<C> Cs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<BaseClass>()
.HasMany<A>(b => b.ManyA)
.WithRequired(a => a.BaseObject)
.WillCascadeOnDelete(true);
}
}
public class BaseClass
{
public BaseClass() { ManyA = new HashSet<A>(); }
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public virtual ICollection<A> ManyA { get; set; }
}
public class A
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public BaseClass BaseObject { get; set; }
public string Foo { get; set; }
}
public class B : BaseClass
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public string SomeProperty { get; set; }
}
public class C : BaseClass
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public int SomeOtherProperty { get; set; }
}
并且,基于this Msdn article,将导致Table Per Hierarchy数据库布局。 TPH比TPT表现更好,我认为这可能是一个答案。
我真的希望有更简单的东西,但是性能是底线,毕竟