Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 如何访问具有复合键的表';t模型首先使用代码?_Entity Framework_Ef Code First_Poco_Code First_Entity Framework 5 - Fatal编程技术网

Entity framework 如何访问具有复合键的表';t模型首先使用代码?

Entity framework 如何访问具有复合键的表';t模型首先使用代码?,entity-framework,ef-code-first,poco,code-first,entity-framework-5,Entity Framework,Ef Code First,Poco,Code First,Entity Framework 5,我有一个无法更改的现有数据库,但希望使用EF访问。对于90%的数据库,我已经能够让代码优先EF工作,我印象非常深刻 我遇到了一个案例,我想知道如何通过导航属性建模或访问数据 在一种情况下,表是这样的(这个例子完全是虚构的,但代表了问题): 在表“品种”中,组织表示已定义品种的组织。一只狗可以有几个品种,但程序只显示一个,结果由组织id“过滤”——这是程序设置时配置的值 可能存在的数据示例如下: id organizationID Description 1

我有一个无法更改的现有数据库,但希望使用EF访问。对于90%的数据库,我已经能够让代码优先EF工作,我印象非常深刻

我遇到了一个案例,我想知道如何通过导航属性建模或访问数据

在一种情况下,表是这样的(这个例子完全是虚构的,但代表了问题):

在表“品种”中,组织表示已定义品种的组织。一只狗可以有几个品种,但程序只显示一个,结果由组织id“过滤”——这是程序设置时配置的值

可能存在的数据示例如下:

id    organizationID    Description
 1                 1    Basset Hound
 2                 1    Great Dane
 2                 2    Grande Dane
组织2选择将该品种称为与组织1不同的品种。唯一主键是id和organizationID的组合。狗有一个品种,但没有定义一个或多个相关组织的属性。它从另一个表或配置值(可能是枚举值)中获取附加信息以查找狗的品种

在我的例子中,要找到一个特定的狗品种,你必须有一个狗id和另一条与程序配置相关的信息(组织id)

狗、品种和组织类如下所示:

public class Dog {
  public int id  { get; set; };
  public string name  { get; set; };
  public int breedID  { get; set; };

  public virtual Breed { get; set; }           
}

public class Breed {
  public int id  { get; set; };
  public int organizationID  { get; set; };            
  public string description  { get; set; };

  public virtual Organization { get; set; }  
}

public class Organization {
  public int id  { get; set; };
  public string description  { get; set; };
}
正如在代码中看到的,我希望在返回一个品种的狗上使用“导航”属性,但我不认为我可以首先在代码中配置它

我尝试了一些不同的方法(在fluent API中,将组织排除在外-因为这很容易),并且还将记录我认为不起作用的方法:

1) 
   modelBuilder.Entity<Dog>().HasKey(t => t.id);
   modelBuilder.Entity<Breed>().HasKey(t => t.id);
   modelBuilder.Entity<Dog>().HasRequired(d => d.Breed).WithMany().HasForeignKey(d => d.breedID);
理想情况下,它将像导航集合一样工作,其中EF发挥神奇的作用并返回适当的结果

直观地说,似乎我应该能够使用类似POCO的代码来配置此配置,或者使用/扩展代理来扩展配置,以便在调用访问器时使用我想要的特定查询。或者-看起来我应该能够在任何读操作中填充属性,在写操作中弄脏POCO。我只是对EF不够熟悉,不知道怎么做

这可能吗

作为对第一篇文章的补充,因为我希望保持我的POCO类干净,我想我可能会实现Repository模式来封装像我所描述的那样的复杂查询,并支持其他操作

查看我从代码优先模型生成的EDMX,也不清楚如何从数据库优先的角度实现该模型


任何想法都非常感谢。

简而言之,你不能那样做。如果数据库结构不合理(外键引用非唯一列),则必须将其映射到某个位置。在EF配置中不能这样做,因为它是动态的,所以必须在实体类中这样做。如果不直接调用实体类(或助手类)中的上下文,我看不到任何方法可以做到这一点。

简而言之,您无法做到这一点。如果数据库结构不合理(外键引用非唯一列),则必须将其映射到某个位置。在EF配置中不能这样做,因为它是动态的,所以必须在实体类中这样做。如果不直接调用实体类(或助手类)中的上下文,我看不出有什么方法可以做到这一点。

那太好了。你能给我举个例子说明如何做吗?谢谢我试图配置这个,但没有任何运气。我尝试了一些类似这样的东西:HasRequired(t=>new{t.typeId,otherVariable})。。。问题是,当复合键的另一个组件不是“Dog”表的一部分时,我不知道如何“注入”它。提前谢谢!哦,等等,对不起,我现在知道你的其他情况了,我这样做对你没有帮助。要使用的另一个ID是否存储在数据库的某个位置,或者只有程序知道它?不幸的是,只有程序知道它-这是最初使用数据库的程序工作方式的一部分。谢谢你的回复。问得好,如果你能粘贴一些代表你的问题的代码,那会很有帮助。那太好了。你能给我举个例子说明如何做吗?谢谢我试图配置这个,但没有任何运气。我尝试了一些类似这样的东西:HasRequired(t=>new{t.typeId,otherVariable})。。。问题是,当复合键的另一个组件不是“Dog”表的一部分时,我不知道如何“注入”它。提前谢谢!哦,等等,对不起,我现在知道你的其他情况了,我这样做对你没有帮助。要使用的另一个ID是否存储在数据库的某个位置,或者只有程序知道它?不幸的是,只有程序知道它-这是最初使用数据库的程序工作方式的一部分。感谢您的回复。很好,如果您可以粘贴一些表示您的问题的代码,这将非常有帮助。在这种情况下,在调用Breed的访问器时,是否有方法调用特定的查询?我想知道我是否可以先用类似POCO的EF来补充代码(到目前为止效果很好)。不,你必须自己做,就像你在post中已经包含的代码一样。既然如此,当调用Breed的访问器时,有没有办法调用特定的查询?我想知道我是否可以先用类似POCO的EF补充代码(到目前为止效果很好)。不,你必须自己做,就像你在帖子中已经包含的代码一样。
1) 
   modelBuilder.Entity<Dog>().HasKey(t => t.id);
   modelBuilder.Entity<Breed>().HasKey(t => t.id);
   modelBuilder.Entity<Dog>().HasRequired(d => d.Breed).WithMany().HasForeignKey(d => d.breedID);
2) 
   Change class dog:
      Remove:
          public virtual Breed { get; set; }
      Add:
          public virtual ICollection<Breed> Breeds { get; set; }

          public Breed Breed {
            get {
              // Assume 1 is configured organization value
              return Breeds.Single(t => t.OrganizationId == 1);
            };
            set {
              Breeds.Add(value);
            }
          }

     Change model:
        I don't know how to do this for the given classes.  Since it's a Collection, it must look something like

        modelBuilder.Entity<Dog>().HasMany(d => d.Breeds)...

        but I don't see how to specify that breedID is a foriegn key into the breed table.
 3)
    Change model to account for composite key (using first set of classes):
       modelBuilder.Entity<Breed>().HasKey(b => new { b.id, b.organizationId });

       modelBuilder.Entity<Dog>().HasRequired(t => t.Breed).WithMany().HasForeignKey(t => new { t.breedID, configuredValue });
public Breed Breed {
   get {
      return context.Breed.Where(b => b.id == this.id && b.organizationID == 1).Single();
   }
}