В вашем случае код для Code-First будет выглядеть
примерно так:
[Table("Role")]
public class Role
{
[Column("id"), Key]
public int Id { get; set; }
[Column("name"), Required]
public string Name { get; set; }
}
[Table("User")]
public class User
{
[Column("id"), Key]
public int Id { get; set; }
[Column("name"), Required]
public string Name { get; set; }
[Column("password"), Required]
public string Password { get; set; }
[Column("role_id"), ForeignKey("Role")]
public int RoleId { get; set; }
public virtual Role Role { get; set; }
[InverseProperty("Creator")]
public virtual List<Bid> BidsWhereUserAsCreator { get; set; }
[InverseProperty("Executor")]
public virtual List<Bid> BidsWhereUserAsExecutor { get; set; }
}
[Table("bid")]
public class Bid
{
[Column("id"), Key]
public int Id { get; set; }
[Column("Text"), Required]
public string Text { get; set; }
[Column("DateTime_Created")]
public DateTime Created { get; set; }
[Column("user_id_created"), ForeignKey("Creator")]
public int CreatorId { get; set; }
[Column("user_id_executor"), ForeignKey("Executor")]
public int ExecutorId { get; set; }
public virtual User Creator { get; set; }
public virtual User Executor { get; set; }
}
public class MyDbContext : DbContext
{
public virtual DbSet<Role> Roles { get; set; }
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<Bid> Bids { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// убираем каскадное удаление
// http://stackoverflow.com/questions/17127351/introducing-foreign-key-constraint-may-cause-cycles-or-multiple-cascade-paths
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
}
public static void Test()
{
using (MyDbContext dbContext = new MyDbContext())
{
// говорим, что не надо создавать динамически генерируемые прокси-классы
// (которые System.Data.Entity.DynamicProxies...)
dbContext.Configuration.ProxyCreationEnabled = false;
// отключаем ленивую загрузку
dbContext.Configuration.LazyLoadingEnabled = false;
// поля класса будут заполнены, но данные навигационных свойств загружены не будут.
List<Bid> bidsOnly = dbContext.Bids.ToList();
// поля навигационных свойств можно загрузить через Include
List<Bid> bidsWithAllInfo = dbContext.Bids.Include(b => b.Creator).Include(b => b.Executor).Include(b => b.Creator.Role).Include(b => b.Executor.Role).ToList();
// данные для навигационного поля Creator будут загружены автоматически
IEnumerable<Bid> bids = dbContext.Bids.Include(b => b.Executor).Where(b => b.Creator.RoleId == 1).ToList().Select(
b => new Bid()
{
Id = b.Id,
Text = b.Text,
Created = b.Created,
Creator = new User() { Name = b.Creator.Name },
Executor = new User() { Name = b.Executor.Name }
});
}
}
}
В описанном вами случае ни ленивая загрузка, ни прокси-классы не мешают получать требуемый результат и конфигурацию по-умолчанию можно не менять.