当实体设置为内部访问时,DbContext EntitySet为null

时间:2013-02-26 08:46:17

标签: dbcontext internal dbset

我希望db set是内部的,以确保外部包只能访问和编程接口而不是具体类

e.g。

namespace Domain
{
    public interface IProduct
    {
        string Description { get; }
        int Id { get; }
        decimal Price { get;  }
    }
}



//Separate Person.cs file for custom logic
namespace Domain
{
    internal partial class Product :IProduct
    {
    }
}

internal partial class POS : DbContext
{
    public POS()
        : base("name=POS")
    {
    }   

    internal DbSet<Product> Products { get; set; }
}

//The other Person.cs file is generated by the .tt file 

//_context.People is null which caused the dreaded null pointer exception :(
var people = _context.People.ToList();  

只要我通过模型浏览器设置对Person类和People实体设置为public的访问权限,它就会再次运行,但是我想限制对内部的访问以进行包封装。

它在VS2010 EF中与Context配合使用,但在VS2012中与DbContext配合使用。

非常感谢任何帮助:}

P.S。

现在我刚刚编辑了.tt文件,如下所示

public <#=code.Escape(container)#>()
    : base("name=<#=container.Name#>")
{
    Products = Set<Product>(); 

这将生成如下所示的上下文类,它实例化该集合,不必将其添加到模型中每个实体集的.tt文件中。

internal partial class POS : DbContext
{
    public POS()
        : base("name=POS")
    {
         Products = Set<Product>(); 
    }

1 个答案:

答案 0 :(得分:0)

我知道这个问题已经过时了,但我也遇到了这个问题。根据其他一些StackOverflow帖子,这仍然是EntityFramework的行为,解决方案仍然是明确地Set<>实体集。

也就是说,我没有手动将每个实体名称添加到.tt文件中,而是创建了一些代码,这些代码将导致TT文件为每个实体自动生成此代码。

*.Context.tt文件中,您应该发现构造函数的代码如下所示:

    public <#=code.Escape(container)#>()
        : base("name=<#=container.Name#>")
    {
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
        this.Configuration.LazyLoadingEnabled = false;
<#
}
#>
    }

修改此内容现在看起来像:

   public <#=code.Escape(container)#>()
        : base("name=<#=container.Name#>")
    {
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
        this.Configuration.LazyLoadingEnabled = false;
<#
}
#>

<#
    foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
    {
#>
        <#=codeStringGenerator.SetStatement(entitySet)#>

<#
}
#>
    }

在文件的下方,您应该看到CodeStringGenerator类的类定义,添加一个新方法(我在第307行的DbSet方法定义下直接添加了我的方法):

public string SetStatement(EntitySet entitySet)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} = Set<{1}>();",
        _code.Escape(entitySet),
        _typeMapper.GetTypeName(entitySet.ElementType));
}

保存模板时,它应该为模型中的每个实体重新生成DbContext类,其中包含Set<>语句。添加的新实体将重新触发模板生成,并且这些新实体也将包含在构造函数中。