Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.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
C# 实体框架在模型C中不映射多个列表#_C#_Asp.net Mvc_Entity Framework_Ef Fluent Api - Fatal编程技术网

C# 实体框架在模型C中不映射多个列表#

C# 实体框架在模型C中不映射多个列表#,c#,asp.net-mvc,entity-framework,ef-fluent-api,C#,Asp.net Mvc,Entity Framework,Ef Fluent Api,我有一个类“Project”,它有两个列表,一个是“Employee”,另一个是“tool”,当我只使用其中一个列表构建项目时,数据库会以正确的关系更新,如果将第二个列表添加到类实体框架中,则无法了解如何创建关系 public class Project { public Guid Id { get; set; } public List<Employee> RequiredEmployees {get;set;} public List&l

我有一个类“Project”,它有两个列表,一个是“Employee”,另一个是“tool”,当我只使用其中一个列表构建项目时,数据库会以正确的关系更新,如果将第二个列表添加到类实体框架中,则无法了解如何创建关系

 public class Project
{        
    public Guid Id { get; set; }
    public List<Employee> RequiredEmployees {get;set;}
    public List<Tools> RequiredTools {get;set;}
}

Public class Tool
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public Project Project { get; set; }
    public Guid ProjectId { get; set; }
}
公共类项目
{        
公共Guid Id{get;set;}
公共列表RequiredEmployees{get;set;}
公共列表所需工具{get;set;}
}
公共类工具
{
公共Guid Id{get;set;}
公共字符串名称{get;set;}
公共项目{get;set;}
公共Guid项目ID{get;set;}
}
我得到错误“引用的表中没有主键或候选键” 我曾尝试在ModelBuilder中映射,但没有成功

 modelBuilder.Entity<Employee>()
    .HasRequired<Project>(s => s.Project)
    .WithMany(g => g.Employee)
    .HasForeignKey<Guid>(s => s.ProjectId);
modelBuilder.Entity()
.HasRequired(s=>s.Project)
.WithMany(g=>g.Employee)
.HasForeignKey(s=>s.projectd);

有什么想法吗?

当然,我们需要查看您的
工具
类,但我认为问题在于实体框架找不到用作主键的属性


实体框架约定将类的主键命名为
Id
Id
(在本例中为
ToolsId
)。如果您希望一个名称与此名称不同的属性作为PK,则必须使用或显式地指定它。

您已经在几个问题上进行了调整。报告的错误与主键有关。此外,您在指定一对多关系时遇到问题

一对多关系

实体框架是很容易的,如果您遵循的每一个偏差,您需要告诉实体框架有关您的偏差

您计划在
项目
工具
之间设计一对多:每个
项目
都有零个或多个
工具
,每个
工具
只属于一个
项目

如果您遵循的是惯例,则不必将此关系告知实体框架;实体框架将按约定检测关系:

  • 使用ICollection而不是列表,毕竟,
    RequiredTools[4]
    意味着什么
  • 使ICollection虚拟化。只要您的项目是一个查询,它就不是一个真正的ICollection,它只包含一个可以生成ICollection的类
考虑使用适当的命名约定:

class Project
{        
    public Guid Id { get; set; }
    // a project has zero or more Employees:
    public virtual ICollection<Employee> Employees {get;set;}
    // a project has zero or more Tools
    public virtual ICollectioin<Tool> Tools {get;set;}
}
类似地:每个员工都属于一个项目

class Employee
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public Guid ProjectId {get; set;}
    public virtual Project Project { get; set; }
}
或者,如果员工可以参与多个项目,则使用:

class Employee
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    // an Employee works in zero or more Projects
    public virtual ICollection<Project> Projects { get; set; }
}
如果忘记实现Id,编译器将警告您。GenerateID现在相当简单:

private void GenerateIds()
{
    foreach (DbEntityEntry addedEntry in this.ChangeTracker.Entries()
       .Where(entry => entry.State == EntityState.Added))
    {
        // every entry implements IPrimaryKey. Fill the Id           
        (IPrimaryKey)entry.Id = this.CreateId
    }
}

private GUID CreateId()
{
    return Guid.NewGuid(); // or use your own Guid creator
}

您可以在主键字段中添加
KeyAttribute
[key]public Guid Id{get;set;}
,然后运行
Update Database
。发布
Tools
类。EF在那里找不到钥匙。如果可能的话,将其重命名为
Tool
。此外,它将是
。对于许多(g=>g.RequiredEmployees)
我已经添加了简化的“Tool”类,并且我已经在id上添加了[Key],它仍然不起作用。“不起作用”从来都不是很清楚或者很有用。发布准确的错误消息和所涉及的准确行。我已经添加了[Key]public Guid Id{get;set;},但这并不能很好地回答这个问题!“您选择不使用常规类型作为主键”是什么意思?您的意思是OP使用了
Guid
而不是
int
?我们不能用[DatabaseGenerated(DatabaseGeneratedOption.Identity)]完成同样的PK装饰吗?不,我不是这个意思。我的意思是,一个人没有
Id
PersonId
作为主键,而一个订单没有
Id
OrderId
作为主键。如果您使用这些标识符中的一个,实体框架将假定这是主键。如果您选择使用不同的标识符,则t.o将告诉实体框架主键的名称
class MyDbContext : DbContext
{
    public DbSet<Employee> Employees {get; set;}
    public DbSet<Project> Projects {get; set;}
    public DbSet<Tool> Tools {get; set;}
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    // a Project has zero or more Tools via property RequiredTools and table TableName:
    var entityProject = modelBuilder.Entity<Project>();
    entityProject.ToTable(... /* table name */);
    // a project has zero or more tools via property RequiredTools
    // every tool belongs to one required Project 
    // using foreign key ProjectId
    entityproject.HasMany(project => project.RequiredTools)
        .WithRequired(tool => tool.Project)
        .HasFreignKey(tool => tool.ProjectId);
}
public override int SaveChanges()
{
    GenerateIds();
    return base.SaveChanges();
}
public override Task<int> SaveChangesAsync()
{
    GenerateIds();
    return base.SaveChangesAsync();
}
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken)
    {
        this.GenerateIds();
        return base.SaveChangesAsync(cancellationToken);
    }
public interface IPrimaryKey
{
     GUID Id {get; set;}
}

class Tool : IPrimaryKey {...}
class Project : IPrimaryKey {...}
private void GenerateIds()
{
    foreach (DbEntityEntry addedEntry in this.ChangeTracker.Entries()
       .Where(entry => entry.State == EntityState.Added))
    {
        // every entry implements IPrimaryKey. Fill the Id           
        (IPrimaryKey)entry.Id = this.CreateId
    }
}

private GUID CreateId()
{
    return Guid.NewGuid(); // or use your own Guid creator
}