簡體   English   中英

實體框架跳過一個數據庫字段值

[英]Entity framework skip one db field value

我有一個很小的項目,只是要了解“代碼優先”的方法。

當我使用“代碼優先”創建數據庫並添加對象時,它運行良好,該對象的所有屬性都保存在數據庫中。 然后,我嘗試獲取保存的對象。 它返回對象,但是一個屬性始終為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);                
}

結果是

在此處輸入圖片說明

更新

我也必須說

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

效果很好,它返回絕對正確的值。

現在最簡單的方法來檢測問題的實際出處,以查看由Get執行的生成的select語句。 對於實體框架6:

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

這樣,您將看到真正執行的腳本,從而為您提供更清晰的圖像,確切地顯示出下降的位置。

關於模型,我認為Material和ItemStatus是枚舉,否則我建議將屬性標記為虛擬(用於延遲加載)。

我也不太確定您的存儲庫實現。 每個EfGenericRepository都有其自己的上下文,而且我不確定這是否是一個好的設計不是問題的主題。

答案:
您的模型包含一個名為TopBidderId的字符串屬性。 創建數據庫時,字段類型類似於“文本”(最近的SQL Server中的varchar(max),MySQL,CLOB等中的文本)。 因此,在其中可以編寫一個字符串。 在您的情況下,它似乎是Guid的ToString。 讀取內容時,該字符串將插入TopBidderId屬性中。
絕不會發生這種情況,無法將text(或varchar(max))列轉換為模型的TopBidderId的字符串。

順便說一句,我嘗試運行您的代碼(從上下文開始,而不是從IdentityDbContext開始,添加兩個缺少的枚舉和Repository類,默認遷移),並且可以按預期工作。

那么,為什么在您的情況下不起作用? 我認為您的數據庫模型與實體模型不符(TopBidderId列不是文本或varchar max)。 通常不會發生,但是在某些情況下會發生。 例如,如果禁用模型檢查(在實體模型和__MigrationHistory表的內容之間進行檢查),或者在遷移數據庫后更改了TopBidderId列類型。

另一種情況是您的實體模型與您在此處發布的模型不同(並且TopBidderId是Bidder類型的屬性TopBidder使用的外鍵)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM