15

我正在玩新的 EF4.1 独角兽之爱。

我试图了解我可以使用代码优先的不同方式以编程方式定义我在几个简单 POCO 之间的关系。

我如何定义以下 =>

  1. 1Team有 0-many User。(并且 aUser在 1 中Team
  2. 1User有 0-or-1 Foo(但 aFoo没有返回 a 的属性User
  3. 1User有 1UserStuff
4

2 回答 2

11

这里有您正在寻找的示例:

public class User
{
    public int Id { get; set; }
    ...
    public Foo Foo { get; set; }
    public Team Team { get; set; }
    public UserStuff UserStuff { get; set; }
}

public class Team
{
    public int Id { get; set; }
    ...
    public ICollection<User> Users { get; set; }
}

public class Foo
{
    public int Id { get; set; }
    ...
}

public class UserStuff
{
    public int Id { get; set; }
    ...
}

public class Context : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Foo> Foos { get; set; }
    public DbSet<Team> Teams { get; set; }
    public DbSet<UserStuff> UserStuff { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .HasRequired(u => u.Team)
            .WithMany(t => t.Users);

        modelBuilder.Entity<User>()
            .HasOptional(u => u.Foo)
            .WithRequired();

        modelBuilder.Entity<User>()
            .HasRequired(u => u.UserStuff)
            .WithRequiredPrincipal();
    }
}
于 2011-03-20T15:08:41.070 回答
5

让我们介绍几个具体的类来说明解决方案:

public class Account
{
    public long ID { get; set; }
    public virtual User User { get; set; }
}

public class User
{
    public long ID { get; set; }
    public virtual Account Account { get; set; }
    public virtual Team Team { get; set; }
}

public class Team
{
    public long ID { get; set; }
    public long CompanyID { get; set; }

    public virtual Company Company { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

public class Company
{
    public long ID { get; set; }
}

我正在使用一个帮助类来使映射类不那么冗长:

internal abstract class AbstractMappingProvider<T> : IMappingProvider where T : class
{
    public EntityTypeConfiguration<T> Map { get; private set; }

    public virtual void DefineModel( DbModelBuilder modelBuilder )
    {
        Map = modelBuilder.Entity<T>();

        Map.ToTable( typeof(T).Name );
    }
}

现在用于映射。让我们先进行“1:1”映射。在我的示例中,用户和帐户是 1:1 相关的,并且共享相同的主键(其中只有一个是身份列,在本例中是 Account.ID)。

internal class UserMapping : AbstractMappingProvider<User>
{
    public override void DefineModel( DbModelBuilder modelBuilder )
    {
        base.DefineModel( modelBuilder );
        Map.HasRequired( e => e.Account ).WithRequiredDependent( r => r.User ).WillCascadeOnDelete( true );
    }
}

internal class AccountMapping : AbstractMappingProvider<Account>
{
    public override void DefineModel( DbModelBuilder modelBuilder )
    {
        base.DefineModel( modelBuilder );
        Map.HasRequired( e => e.User ).WithRequiredPrincipal( r => r.Account ).WillCascadeOnDelete( true );
    }
}   

在以下映射中,我们指定一个团队有 (0..n) 个用户,而单个用户恰好在一个团队中(必需)。我们还指定一个团队可以拥有一个公司,但公司不会公开团队列表。

internal class TeamMapping : AbstractMappingProvider<Team>
{
    public override void DefineModel( DbModelBuilder modelBuilder )
    {
        base.DefineModel( modelBuilder );
        Map.HasOptional( e => e.Company ).WithMany().HasForeignKey( e => e.CompanyID );
        Map.HasMany( e => e.Users ).WithRequired( r => r.Team );
    }
}   

internal class CompanyMapping : AbstractMappingProvider<Company>
{
    public override void DefineModel( DbModelBuilder modelBuilder )
    {
        base.DefineModel( modelBuilder );
    }
}

希望这可以帮助!

于 2011-03-20T14:55:29.547 回答