EF将列添加到桥接表并访问数据

时间:2016-06-16 22:59:48

标签: c# entity-framework many-to-many

我在两个表之间有多对多的关系。 EF创建(模型优先)为我创建了桥表,其中两列将两个键链接在一起。一切都好又好。但我想在桥接表中添加几列,以保存与特定关系相关的其他数据。

如果我在桥接表上执行alter table add <column name>,那么如何使用EF访问数据?可能吗?我想我总是可以做一个直接的SQL查询..但那就是90年代。

3 个答案:

答案 0 :(得分:1)

手动设置桥接表:

public class User
{
    // User stuff

    // Bridge table
    public virtual ICollection<UserFile> Files { get; set; }
}

public class File
{
    // Other File stuff ....

    // Bridge table
    public virtual ICollection<UserFile> Users { get; set; }
}

// Bridge table
public class UserFile
{
    public User User { get; set; }
    public File File { get; set; }

    public DateTime CreatedDate { get; set; }
    // Other metadata here.
}

您可能需要在上下文覆盖OnModelCreating()

中设置关系
 modelBuilder.Entity<UserFile>()
    .HasRequired(i => i.User)
    .WithMany(i => i.Files)
    .WillCascadeOnDelete(true);

答案 1 :(得分:1)

以下是您如何做到这一点的示例:

默认的brdige表名是

dbo.Table1NameTable2Name但你可以自定义它。

你也可以使用automapper创建一个通用的灵魂。

示例:

public class Account
{
    public int AccountId { get; set; }
    public virtual List<Operation> Operations { get; set; }
}

public class Operation
{
    public Int32 OperationId { get; set; }
    public virtual List<Account> Accounts { get; set; }
}

public class MyDbContext : DbContext
{
    public DbSet<Operation> Operations { get; set; }
    public DbSet<Account> Accounts { get; set; }
    public MyDbContext()
        : base("name=cs")
    {
    }
}

public class OperationAccounts
{
    public int AccountId { get; set; }
    public int OperationId { get; set; }
    public string ExtraInfo { get; set; }
}

public static ICollection<OperationAccounts> GetOperationAccounts(string connectionString = @"Data Source=.\;Initial Catalog=TestDb;Integrated Security=true")
{
    ICollection<OperationAccounts> dict = new List<OperationAccounts>();
    var sqlBuilder = new SqlConnectionStringBuilder(connectionString);
    using (var con = new SqlConnection(connectionString))
    {
        con.Open();
        var cmd = con.CreateCommand();
        cmd.CommandText = "SELECT * FROM OperationAccounts";

        using (var rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection))
        {
            while (rdr.Read())
            {
                var accountId = rdr.GetInt32(0);
                var opertationId = rdr.GetInt32(1);
                var extraColumn = rdr.IsDBNull(2)? string.Empty : rdr.GetString(2);

                dict.Add(new OperationAccounts() { AccountId = accountId, OperationId = opertationId, ExtraInfo = extraColumn });
            }
        }
    }
    return dict;
}

public static void SetOperationAccounts(ICollection<OperationAccounts> operationAccounts, string connectionString = "name=cs")
{
    // Your homework same as GetOperationAccounts
}

static void Main(string[] args)
{
    Database.SetInitializer<MyDbContext>(new CreateDatabaseIfNotExists<MyDbContext>());
    using (var dbContext = new MyDbContext())
    {
        dbContext.Database.ExecuteSqlCommand(@"ALTER TABLE OperationAccounts ADD ExtraInfo VARCHAR(20) NULL; ");
        var account = new Account();
        var operation = new Operation();

        account.Operations = new List<Operation> { operation };
        operation.Accounts = new List<Account> { account };

        dbContext.Accounts.Add(account);
        dbContext.SaveChanges();

        var oas = GetOperationAccounts();
        foreach (var oa in oas)
        {
            oa.ToString();
        }
    }
}

答案 2 :(得分:0)

您可以使用默认的桥接表,但是有一种更简单的方法。这是带有额外字段的桥表示例。 在此示例中,我们有两个实体表和一个桥表

public class Student
 {
    public int id { get; set; }
    public string FullName { get; set; }
    public IList<CourseStudent> CourseStudents { get; set; }
 }
public class Course
 {
    public int id { get; set; }
    public string CourseName { get; set; }
    public IList<CourseStudent> CourseStudents { get; set; }
 }

  //bridge Table
    public class CourseStudent
{
    public Student Student { get; set; }
    [Key, Column(Order = 0)]
    public int Studentid { get; set; }

    public Course Course { get; set; }
    [Key, Column(Order = 1)]
    public int Courseid { get; set; }

    //You can add foreign keys like this
    //public Yourclass Yourclass{ get; set; }
    //[key, Column(Order = )]
    //public Yourclasstype(int,string or etc.) Yourclassid{ get; set; }

    //Other data fields
    public DateTime RegisterDate { get; set; }
}

现在将其添加到您的DBcontext

 public class Yourdbcontextname: DbContext
{
    public BridgeDB() : base("name=EFbridge")
    {
    }
    public DbSet<Student> Students { get; set; }
    public DbSet<Course> Courses { get; set; }
    public DbSet<CourseStudent> CourseStudents { get; set; }
}