Entity Framework - Свободный API - Создание странных столбцов PK: FK FK - PullRequest
0 голосов
/ 05 июля 2018

Мой проект База данных сначала , и я использую Entity Framework 6.2.0.

Итак, у меня есть следующие классы в простой иллюстрации:

Person [1]    [n] Link_Table [n]    [1] Area
======            ==========            ====
ID                ID                    ID 
                  PersonID (FK)         
                  AreaID (FK)

Теперь при использовании следующего кода через меня будет внутреннее исключение «недопустимое имя столбца 'Area2_ID'".

Db_Context db = new Db_Context();

// getting all links with specific "personID"
List<Link_Table> links = db.Link_Table.Where(item => item.PersonID == personID).ToList();

// now getting all areas
List<Area> areas= new List<Area>();
foreach (Link_Table link in links)
{
    // ERROR
    areas.Add(db.Area.Where(item => item.ID == link.areaID).First());
}

Я уже читал немного об этой проблеме другими пользователями, и проблема должна быть в (автоматически сгенерированном) OnModelCreating .

modelBuilder.Entity<Area>()
            .Property(e => e.Description)
            .IsUnicode(false);

        modelBuilder.Entity<Area>()
            .HasOptional(e => e.Area1)
            .WithRequired(e => e.Area2);

По какой-либо причине, используя EF в коде и создавая новый Area-Object, он покажет мне не только "ID" -Property, но также "Area1" - и "Area2" -Property.

Вопрос Как я должен справиться с этим? Столбцы «Area1_ID» и «Area2_ID» существуют только в EF, но не в базе данных. Могу ли я удалить эти свойства или что-то еще, чтобы предотвратить исключение?

EDIT: Мои модели:

[Table("Area")]
public partial class Area
{
    public Guid ID { get; set; }

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

    [Column(TypeName = "text")]
    public string Description{ get; set; }

    public virtual Area Area1 { get; set; }

    public virtual Area Area2 { get; set; }
}

public partial class Link_Table
{
    public Guid ID { get; set; }

    public Guid? Person_ID { get; set; }

    public Guid? Area_ID { get; set; }

    public virtual Person Person{ get; set; }
}

[Table("Person")]
public partial class Person
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Person()
    {
        Link_Table = new HashSet<Link_Table>();
    }

    public Guid ID { get; set; }
}

Ответы [ 3 ]

0 голосов
/ 05 июля 2018

Не очень ясно для меня ваша цель, но вы можете изменить свой код следующим образом:

этот код:

// now getting all areas
List<Area> areas= new List<Area>();
foreach (Link_Table link in links)
{
    // ERROR
    areas.Add(db.Area.Where(item => item.ID == link.areaID).First());
}

можно заменить на:

var areas=links.Select(link => link.Area).ToList() // if you decide to add a navigation property

или

var areas=db.Areas.Where(area => links?.Any(link=>link.areaID==area.Id)).ToList();

Скорее всего, вы получили ошибку .First() для будущего использования .FirstOrDefault()

Пожалуйста, смотрите ниже пример первой реализации кода:

class Program
{
    static void Main(string[] args)
    {
        var db = new ApplicationDbContext();
        var person = new Person();
        IQueryable<Link> personLinks = db.Links.Where(x => x.PersonId == person.Id);
        List<Area> personAreas = personLinks.GroupBy(x => x.Area).Select(x => x.Key).ToList(); 
    }
}

public class Person
{
    public int Id { get; set; }
    public ICollection<Link> Links { get; set; }
}

public class Link
{
    public int Id { get; set; }
    public int PersonId { get; set; }
    public Person Person { get; set; }
    public int AreaId { get; set; }
    public Area Area { get; set; }
}

public class Area
{
    public int Id { get; set; }
    public ICollection<Link> Links { get; set; }
}

public class ApplicationDbContext : DbContext
{
    public DbSet<Person> Persons { get; set; }
    public DbSet<Area> Areas { get; set; }
    public DbSet<Link> Links { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Link>()
            .HasRequired(x => x.Person)
            .WithMany(x => x.Links)
            .HasForeignKey(x => x.PersonId)
            .WillCascadeOnDelete(true);

        modelBuilder.Entity<Link>()
            .HasRequired(x => x.Area)
            .WithMany(x => x.Links)
            .HasForeignKey(x => x.AreaId)
            .WillCascadeOnDelete(false);

        base.OnModelCreating(modelBuilder);
    }
}

здесь вы можете узнать больше о коде структуры сущностей сначала перейдите по этой ссылке

0 голосов
/ 05 июля 2018

Когда вы в последний раз запускали миграцию базы данных? Если ваша модель верна и ваша база данных сообщает, что пропущены поля, значит, база данных не соответствует коду.

0 голосов
/ 05 июля 2018

Эта строка выглядит подозрительно:

areas.Add(db.Area.Where(item => item.ID == link.areaID).First());

item.ID - это индекс записи таблицы ссылок, а не записи области.

areas.Add(db.Area.Where(item => item.AreaID == link.areaID).First());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...