映射私有属性时出现问题

时间:2012-10-04 04:50:17

标签: entity-framework code-first private-members

我有两个实体类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 ,则上述两种方式都可以。

在这种情况下出了什么问题?

2 个答案:

答案 0 :(得分:0)

属性必须公开才能使代理工作。见here

答案 1 :(得分:0)

删除GetProducts并执行此操作:

public virtual List<Product> Products {get; protected set;}

注意setter上的protected关键字。我刚试过这个,它对我来说很好。