C# 实体框架跳过一个db字段值

C# 实体框架跳过一个db字段值,c#,entity-framework,ef-code-first,C#,Entity Framework,Ef Code First,我有一个非常小的项目,只是为了理解“代码优先”的方法 当我使用“代码优先”创建一个数据库并添加一个对象时——效果很好,对象的所有属性都保存在数据库中。 然后我尝试获取保存的对象。它返回对象,但有一个属性始终为空 谁能解释一下我的代码有什么问题吗 实体类 public class Item { public Guid Id { get; set; } public string OwnerId { get; set; } public Dat

我有一个非常小的项目,只是为了理解“代码优先”的方法

当我使用“代码优先”创建一个数据库并添加一个对象时——效果很好,对象的所有属性都保存在数据库中。 然后我尝试获取保存的对象。它返回对象,但有一个属性始终为空

谁能解释一下我的代码有什么问题吗

实体类

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 void GetEntity(Guid id)
{
    var context = new Repository();
    var auction = context.ItemRepository.Get().FirstOrDefault(i => i.Id == id);                
}
结果是

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; }                
}

更新

我还必须说,

var request = "SELECT TopBidderId FROM Items WHERE Id = '*item_id*'";
var result = _dbContext.Database.SqlQuery<string>(request).FirstOrDefaultAsync().Result;
var request=“从Id='*item_Id*'的项目中选择TopBidderId”;
var result=_dbContext.Database.SqlQuery(request).FirstOrDefaultAsync().result;

它工作得很好,返回的值绝对正确。

现在最简单的检测问题实际发生在哪里的方法是查看Get执行的生成的select语句。对于实体框架6:

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

通过这一点,您将看到实际执行的脚本,从而更清楚地了解问题的具体位置。

现在最简单的方法是检测问题的实际位置,以查看Get执行的生成的select语句。对于实体框架6:

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

通过这一点,您将看到实际执行的脚本,以便更清楚地了解下降的确切位置。

关于模型,我认为Material和ItemStatus是枚举,否则我建议将属性标记为虚拟(用于延迟加载)

我也不太确定您的存储库实现。每个EfGenericRepository都有自己的背景,我不确定这是否是一个好的设计,但这不是问题的主题

答案是:
您的模型包含名为TopBidderId的字符串属性。创建数据库时,字段类型类似于“text”(最近的SQL Server中的varchar(max)、MySQL中的text、CLOB等)。所以,在它里面,你可以写一个字符串。在您的例子中,它似乎是一个Guid的ToString。读取内容时,字符串将插入TopBidderId属性。
不可能不发生这种情况,text(或varchar(max))列可以转换为模型的topbiderid的字符串

顺便说一句,我试着运行代码(从上下文开始,而不是从IdentityDbContext开始,添加两个缺少的枚举和存储库类,默认迁移),它按照预期工作

那么为什么在你的情况下不起作用呢?我认为您的数据库模型与实体模型不一致(并且topbiderid列不是text或varchar max)。通常它不会发生,但在某些情况下它可能发生。例如,如果禁用了模型检查(在实体模型和uu MigrationHistory表的内容之间进行检查),或者在迁移数据库后更改了TopBidderId列类型


另一种情况是,您的实体模型与您在此处发布的实体模型不同(TopBidderId是类型为Bidder的属性TopBidder使用的外键)。

关于模型,我认为Material和ItemStatus是枚举,否则我建议将属性标记为虚拟(用于延迟加载)

我也不太确定您的存储库实现。每个EfGenericRepository都有自己的背景,我不确定这是否是一个好的设计,但这不是问题的主题

答案是:
您的模型包含名为TopBidderId的字符串属性。创建数据库时,字段类型类似于“text”(最近的SQL Server中的varchar(max)、MySQL中的text、CLOB等)。所以,在它里面,你可以写一个字符串。在您的例子中,它似乎是一个Guid的ToString。读取内容时,字符串将插入TopBidderId属性。
不可能不发生这种情况,text(或varchar(max))列可以转换为模型的topbiderid的字符串

顺便说一句,我试着运行代码(从上下文开始,而不是从IdentityDbContext开始,添加两个缺少的枚举和存储库类,默认迁移),它按照预期工作

那么为什么在你的情况下不起作用呢?我认为您的数据库模型与实体模型不一致(并且topbiderid列不是text或varchar max)。通常它不会发生,但在某些情况下它可能发生。例如,如果禁用了模型检查(在实体模型和uu MigrationHistory表的内容之间进行检查),或者在迁移数据库后更改了TopBidderId列类型


另一种情况是,您的实体模型与您在此处发布的实体模型不同(TopBidderId是类型为Bidder的属性TopBidder使用的外键)。

数据库中的TopBidderId数据类型是什么?可以是GUID,但不能是字符串?如果数据库和
C
中的
对象的数据类型不匹配,它将始终返回为
null
。尝试将实体类中的
topbiderid
的数据类型从
String
更改为
GUID
topbiderid
的数据类型为
NVARCHAR(MAX)
,它是从实体类生成的,其中
topbiderid
是字符串值。传递的值只是数据库中对象的Id。它与
TopBidderId
值无关数据库中的TopBidderId数据类型是什么?可以是GUID,但不能是字符串?如果数据库和
C
中的
对象的数据类型不匹配,它将始终返回为
null
。尝试将实体类中的
topbiderid
的数据类型从