Как получить внешний ключ - PullRequest
0 голосов
/ 22 сентября 2019

(смеется).

Для тех, кого я знаю, я работал (для обучения) над базой данных покемонов.

У меня проблема с созданием базы данных:

У меня 18 разных типов:

"Acier" 
"Combat" 
"Dragon" 
"Eau" 
"Electrik" 
"Fee" 
"Feu" 
"Glace" 
"Insecte" 
"Normal" 
"Plante" 
"Poison" 
"Psy" 
"Roche" 
"Sol" 
"Spectre" 
"Tenebre" 
"Vol" 

У покемона может быть один тип ИЛИ два: пример: -Pickachu типа Electrik.-Bulbizarre типа Plante and Poison.

Я пытаюсь использовать внешний ключ для создания своей базы данных, но я не знаю, как это сделать, пожалуйста, помогите.

У меня есть модель покемонов:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace Pokemon.Models
{
    [Table("Pokemons")]
    public class Pokemon
    {
        [Key]
        public int PokemonId { get; set; }

        [StringLength(30)]
        public string PokemonName { get; set; }

        [StringLength(30)]
        public string PokemonUsName { get; set; }

        [StringLength(30)]
        public string PokemonDeName { get; set; }

        [StringLength(30)]
        public string PokemonJpName { get; set; }

        public string PokemonDescription { get; set; }

        public int PokemonRate { get; set; }

        public string PokemonImage { get; set; }

        public int PokemonTypeId { get; set; }

        [ForeignKey("PokemonType")]
        public virtual PokemonType PokemonType { get; set; }
    }
}

Модель PokemonTypeModel:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace Pokemon.Models
{
    [Table("PokemonTypes")]
    public class PokemonType
    {
        [Key]
        public int TypeId { get; set; }

        [StringLength(8)]
        public string Type { get; set; }

        public virtual ICollection<Pokemon> Pokemons { get; set; }
    }
}

Надеюсь, я четко задам свой вопрос:

Я хочу сделать покемона "Bulbizarre" с Type1Id = 7 // 7 для plante И type2Id = 24// 24 для яда.

Но некоторые из них имеют только один тип: type1Id 13 // 13 для Electrik и Type2Id = null.// потому что нет второго типа. Экран Table PokemonTypes из базы данных

Ответы [ 2 ]

0 голосов
/ 24 сентября 2019

Я сделал это!Сначала я сделал базу данных и построил ее!

Диаграмма базы данных Это делает меня классом 3 модели, в котором все правильно,

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace DataModels.Models
{
    public partial class Pokemons
    {
        public Pokemons()
        {
            PokemonsPokemonTypes = new HashSet<PokemonsPokemonTypes>();
        }

        public int Id { get; set; }
        public int Num { get; set; }

        [Required]
        [StringLength(30)]
        public string Name { get; set; }

        [StringLength(30)]
        public string UsName { get; set; }

        [StringLength(30)]
        public string JpName { get; set; }

        public int? Rate { get; set; }
        public string Description { get; set; }
        public string Image { get; set; }

        [StringLength(50)]
        public string Kind { get; set; }

        public double? Height { get; set; }
        public double? Weight { get; set; }

        [InverseProperty("Pokemon")]
        public virtual ICollection<PokemonsPokemonTypes> PokemonsPokemonTypes { get; set; }
    }
}

using System.ComponentModel.DataAnnotations.Schema;

namespace DataModels.Models
{
    public partial class PokemonsPokemonTypes
    {
        public int PokemonId { get; set; }
        public int TypeId { get; set; }

        [ForeignKey("PokemonId")]
        [InverseProperty("PokemonsPokemonTypes")]
        public virtual Pokemons Pokemon { get; set; }

        [ForeignKey("TypeId")]
        [InverseProperty("PokemonsPokemonTypes")]
        public virtual PokemonTypes Type { get; set; }
    }
}

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace DataModels.Models
{
    public partial class PokemonTypes
    {
        public PokemonTypes()
        {
            PokemonsPokemonTypes = new HashSet<PokemonsPokemonTypes>();
        }

        public int Id { get; set; }

        [StringLength(8)]
        public string Type { get; set; }

        [InverseProperty("Type")]
        public virtual ICollection<PokemonsPokemonTypes> PokemonsPokemonTypes { get; set; }
    }
}

Это работает довольно хорошо!Один продукт (покемон) может иметь несколько категорий (тип).

0 голосов
/ 23 сентября 2019

В вашем листинге кода есть одна ошибка. Атрибут [ForeignKey] может быть добавлен в свойство внешнего ключа или свойство навигации, но если в свойстве Navigation его необходимо указать, указав имя поля FK.(PokemonTypeId)

Два варианта поддержки нескольких типов покемонов: если у покемона может быть 1 или 2, но не более 2 типов, то вы можете добавить две ссылки PokemonType на покемона.Например:

    public int PrimaryPokemonTypeId { get; set; }
    [ForeignKey("PrimaryPokemonTypeId")]
    public virtual PokemonType PrimaryPokemonType { get; set; }
    public int? SecondaryPokemonTypeId { get; set; }
    [ForeignKey("SecondaryPokemonTypeId")]
    public virtual PokemonType SecondaryPokemonType { get; set; }

Если вы можете сослаться на более чем 2 типа, вы можете принять отношение многие ко многим, а не отношение 1 ко многим.Вы можете ограничить число связанных типов в коде двумя, если хотите, но схема данных будет поддерживать любое количество типов для покемонов.

Покемон будет содержать коллекцию типов.Это означает введение таблицы ссылок.Т.е. PokemonTypePokemon.

Если это EF Core, вам нужно определить таблицу связывания:

public class Pokemon
{
    // ... Pokemon fields...

    public virtual ICollection<PokemonTypePokemon> PokemonTypes { get; set; } = new List<PokemonTypePokemon>();
}

public class PokemonType
{
    // Classifications...

    public virtual ICollection<PokemonTypePokemon> Pokemon { get; set; } = new List<PokemonTypePokemon>();
}    

public class PokemonTypePokemon
{
    public virtual Pokemon { get; set; }
    public virtual PokemonType { get; set; }
}

Это потребует небольшой разводки в DbContext, чтобы связать таблицу связывания.В обработчике DbContext OnModelCreating ...

// EF Core

modelBuilder.Entity<Pokemon>()
   .HasMany(x => x.PokemonTypes)
   .WithOne(x => x.Pokemon)
   .HasForeignKey("PokemonId");

modelBuilder.Entity<PokemonType>()
   .HasMany(x => x.Pokemon)
   .WithOne(x => x.PokemonType)
   .HasForeignKey("PokemonTypeId");

Скорее всего, вам потребуется настроить PK для таблицы PokemonTypePokemon, чтобы использовать составной ключ для PokemonId & PokemonTypeId.

С EF6 выможет отображать HasMany().WithMany(), не требуя карты присоединяющейся таблицы во многих случаях.Это должно дать вам некоторое представление о том, с чего начать с изменения отображения и присоединения к таблице.Сделайте немного гугл-фу на EF Many-to-Many, чтобы уточнить.

...