Платформа сущностей пропускает одно значение поля в БД - PullRequest
0 голосов
/ 11 мая 2018

У меня очень крошечный проект, чтобы понять методологию «сначала код».

Когда я создаю базу данных, используя «сначала код», и добавляю объект - он работает хорошо, все свойства объекта сохраняются в базе данных. Затем я пытаюсь получить сохраненный объект. Возвращает объект, но одно свойство всегда равно null.

Кто-нибудь может объяснить, что не так с моим кодом, пожалуйста?

Класс сущности

public class Item
{
    public Guid Id { get; set; }                
    public string OwnerId { get; set; }
    public DateTime CreationDate { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public bool IsStoreItem { get; set; }
    public decimal Price { get; set; }
    public int Count { get; set; }                          
    public string TopBidderId { get; set; }                 
    public Material Material { get; set; }
    public ItemStatus Status { get; set; }
    public int KrauseNumber { get; set; }                
}

Сущность базы данных

public class ApplicationDbContext : IdentityDbContext<ApplicationIdentityUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false) { }

    public DbSet<Item> Items { get; set; }
    public static ApplicationDbContext Create() => new ApplicationDbContext();                
    }
}

Общий репо

public class EfGenericRepository<T> : IEfGenericRepository<T> where T : class
{
    internal readonly ApplicationDbContext _dbContext;
    internal readonly DbSet<T> _dbSet;

    public EfGenericRepository(ApplicationDbContext dbContext)
    {
        _dbContext = dbContext;
        _dbSet = _dbContext.Set<T>();
    }

    public virtual IEnumerable<T> Get(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "")
    {
        IQueryable<T> query = _dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }
    }
}

Попробуйте получить сущность

public void GetEntity(Guid id)
{
    var context = new Repository();
    var auction = context.ItemRepository.Get().FirstOrDefault(i => i.Id == id);                
}

Результат

enter image description here

UPDATE

Также я должен сказать, что

var request = "SELECT TopBidderId FROM Items WHERE Id = '*item_id*'";
var result = _dbContext.Database.SqlQuery<string>(request).FirstOrDefaultAsync().Result;

прекрасно работает и возвращает абсолютно правильное значение.

Ответы [ 2 ]

0 голосов
/ 13 мая 2018

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

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

Ответ:
Ваша модель содержит строковое свойство с именем TopBidderId. При создании базы данных тип поля похож на «текст» (varchar (max) в последних SQL-серверах, текст в MySQL, CLOB и т. Д.). Итак, внутри него вы можете написать строку. В вашем случае это кажется ToString of Guid. Когда вы читаете содержимое, строка вставляется в свойство TopBidderId.
Ни при каких обстоятельствах этого не происходит, текстовый (или varchar (max)) столбец можно преобразовать в строку TopBidderId вашей модели.

Кстати, я попытался запустить ваш код (начиная с контекста, а не из IdentityDbContext, добавив два отсутствующих перечисления и класс Repository, миграция по умолчанию), и он работает, как и ожидалось.

Так почему в вашем случае не работает? Я думаю, что ваша модель базы данных не соответствует вашей модели сущности (и столбец TopBidderId не является текстом или максимальным значением varchar). Обычно этого не происходит, но в некоторых случаях это может произойти. Например, если вы отключили проверку модели (проверьте между вашей моделью сущности и содержимым таблицы __MigrationHistory) или изменили тип столбца TopBidderId после переноса базы данных.

В другом случае ваша модель сущности отличается от той, которую вы опубликовали здесь (а TopBidderId - это внешний ключ, используемый свойством TopBidder типа Bidder).

0 голосов
/ 11 мая 2018

Самый простой способ на данный момент определить, где на самом деле возникает проблема, чтобы увидеть сгенерированный оператор выбора, выполненный командой Get. Для Entity Framework 6:

public EfGenericRepository(ApplicationDbContext dbContext)
{
    _dbContext = dbContext;
    _dbSet = _dbContext.Set<T>();
    _dbContext.Database.Log = Console.Write; 
}

Таким образом вы увидите реальные выполненные сценарии, чтобы дать вам более четкое изображение, где именно происходит падение.

...