我有两个实体类Project和Product with one-to-many association:
public class Product
{
public string Id {get; set;}
public virtual Project Project {get; set;}
}
public class Project
{
public string Id {get; set;}
protected virtual List<Product> Products {get; set;}
public ReadOnlyCollection<Product> GetProducts()
{
return Products.AsReadOnly();
}
public class PropertyAccessExpressions
{
public static Expression<Func<Project, ICollection<Product>>> Products = x => x.Products;
}
}
public class MyDbContext: DbContext
{
public MyDbContext(string connectionString): base(connectionString){}
public DbSet<Project> Projects {get; set;}
public DbSet<Product> Products {get; set;}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//// project.GetProducts() fails for the following configuratin
//modelBuilder.Entity<Product>()
// .HasRequired(p => p.Project).WithMany(Project.PropertyAccessExpressions.Products);
// The following is OK
modelBuilder.Entity<Project>()
.HasMany(Project.PropertyAccessExpressions.Products).WithRequired(p => p.Project);
}
}
class Program
{
static void Main(string[] args)
{
var context = new MyDbContext(@"data source=localhost;initial catalog=MyTestDb;integrated security=True;");
context.Database.Delete();
context.Database.Create();
var project1 = new Project { Id = "ProjectId1" };
context.Projects.Add(project1);
context.Products.Add(new Product { Id = "ProductId1", Project = project1 });
context.Products.Add(new Product { Id = "ProductId2", Project = project1 });
context.SaveChanges();
var project = context.Projects.ToList()[0];;
var products = project.GetProducts().ToList();
Debug.Assert(products.Count == 2);
}
}
要映射受保护的属性,我使用this solution。
但我遇到了以下问题:
1)如果我使用
配置Project和Product之间的一对多关联modelBuilder.Entity<Product>.HasRequied(p => p.Project).WithMany(Project.PropertyAccessExpressions.Products);
然后Project.GetProducts()失败,似乎延迟加载不起作用。 但如果我改为
modelBuilder.Entity<Project>
.HasMany(Project.PropertyAccessExpressions.Products).WithRequired(p => p.Project);
然后一切都好。
2)如果我将“Project.Products”属性从protected更改为 public ,则上述两种方式都可以。
在这种情况下出了什么问题?
答案 0 :(得分:0)
属性必须公开才能使代理工作。见here
答案 1 :(得分:0)
删除GetProducts
并执行此操作:
public virtual List<Product> Products {get; protected set;}
注意setter上的protected
关键字。我刚试过这个,它对我来说很好。