继承自 DbSet<TEntity> in Entity Framework Code first NullReference
Inherit from DbSet<TEntity> in Entity Framework Code first NullReference
我想对每个添加元素的动作执行nlog。
所以当我做 myContext.Society.Add() 时,我想记录一些东西。
我创建了一个 class DbSetExtension
并修改上下文 StockContext
以使用 DbSetExtension<T>
而不是 DbSet
.
public class DbSetExtension<T> : DbSet<T> where T : class
{
public override T Add(T entity)
{
LoggerInit.Current().Trace("Add Done");
return base.Add(entity);
}
}
当我启动程序时,我注意到我访问了 myContext.Society.Add。
社会是空的。所以我想我的 class DbSetExtension
遗漏了一些东西,但我没有找到。
public class StockContext : DbContext
{
public StockContext()
: base("StockContext")
{
}
public DbSet<HistoricalDatas> HistoricalDatas { get; set; }
public DbSet<Society> Society { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
你有什么想法,
问候,
亚历克斯
[更新]
代码允许添加。
如果我用 DbSet 替换 DbSetExtension,同样的代码可以工作。
所以我的假设是当我从 DbSet 继承时我错过了一些东西。
public bool SetSymbols()
{
CsvTools csvThreat = new CsvTools();
List<Eoddata> currentEnum =
csvThreat.ExtractData<Eoddata>(ConfigurationManager.GetString("FilePathQuotes", ""));
currentEnum.ForEach(
c =>
{
//LoggerInit.Current().Trace("Add Done");
Sc.Society.Add(
new Society()
{
RealName = c.Description,
Symbol = String.Format("{0}.PA", c.Symbol),
IsFind = !String.IsNullOrEmpty(c.Description)
});
});
if (Sc.SaveChanges() > 0)
return true;
return false;
}
在我看来,你的方向完全错误。 DbContext 可以与 DbSet 一起使用,而不是与 DbSetExtension class 一起使用。它能够实例化 DbSet 类型的对象,而不是您自己的类型。这基本上就是您获得此异常的原因。修复它可能需要破解 EF 内部结构,我担心这个问题对您来说只是一个开始。相反,我建议您使用拦截器 classes 使用 EF 进行日志记录的一般方式。这里在文章Logging and Intercepting Database Operations末尾有详细解释。一般来说,这种方法对你来说更有利。为什么?因为 DbContext 只是与 db 通信的中间人。在日志中,您通常关心数据库及其数据发生了什么。如果不延迟调用 SaveChanges,则在 DbSet 上调用 Add 方法可能根本没有任何效果。相反,查询拦截器允许您严格记录与数据库的交互。根据发送到数据库的查询,您可以区分发生了什么。
但是如果你坚持你的方法,我建议你使用扩展方法而不是从 DbSet 派生:
public static class DbSetExtensions
{
public static T LoggingAdd<T>(this DbSet<T> dbSet, T entity)
{
LoggerInit.Current().Trace("Add Done");
return dbSet.Add(entity);
}
}
并这样称呼它:
context.Stock.LoggingAdd(entity);
我想对每个添加元素的动作执行nlog。
所以当我做 myContext.Society.Add() 时,我想记录一些东西。
我创建了一个 class DbSetExtension
并修改上下文 StockContext
以使用 DbSetExtension<T>
而不是 DbSet
.
public class DbSetExtension<T> : DbSet<T> where T : class
{
public override T Add(T entity)
{
LoggerInit.Current().Trace("Add Done");
return base.Add(entity);
}
}
当我启动程序时,我注意到我访问了 myContext.Society.Add。
社会是空的。所以我想我的 class DbSetExtension
遗漏了一些东西,但我没有找到。
public class StockContext : DbContext
{
public StockContext()
: base("StockContext")
{
}
public DbSet<HistoricalDatas> HistoricalDatas { get; set; }
public DbSet<Society> Society { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
你有什么想法, 问候, 亚历克斯
[更新] 代码允许添加。 如果我用 DbSet 替换 DbSetExtension,同样的代码可以工作。 所以我的假设是当我从 DbSet 继承时我错过了一些东西。
public bool SetSymbols()
{
CsvTools csvThreat = new CsvTools();
List<Eoddata> currentEnum =
csvThreat.ExtractData<Eoddata>(ConfigurationManager.GetString("FilePathQuotes", ""));
currentEnum.ForEach(
c =>
{
//LoggerInit.Current().Trace("Add Done");
Sc.Society.Add(
new Society()
{
RealName = c.Description,
Symbol = String.Format("{0}.PA", c.Symbol),
IsFind = !String.IsNullOrEmpty(c.Description)
});
});
if (Sc.SaveChanges() > 0)
return true;
return false;
}
在我看来,你的方向完全错误。 DbContext 可以与 DbSet 一起使用,而不是与 DbSetExtension class 一起使用。它能够实例化 DbSet 类型的对象,而不是您自己的类型。这基本上就是您获得此异常的原因。修复它可能需要破解 EF 内部结构,我担心这个问题对您来说只是一个开始。相反,我建议您使用拦截器 classes 使用 EF 进行日志记录的一般方式。这里在文章Logging and Intercepting Database Operations末尾有详细解释。一般来说,这种方法对你来说更有利。为什么?因为 DbContext 只是与 db 通信的中间人。在日志中,您通常关心数据库及其数据发生了什么。如果不延迟调用 SaveChanges,则在 DbSet 上调用 Add 方法可能根本没有任何效果。相反,查询拦截器允许您严格记录与数据库的交互。根据发送到数据库的查询,您可以区分发生了什么。
但是如果你坚持你的方法,我建议你使用扩展方法而不是从 DbSet 派生:
public static class DbSetExtensions
{
public static T LoggingAdd<T>(this DbSet<T> dbSet, T entity)
{
LoggerInit.Current().Trace("Add Done");
return dbSet.Add(entity);
}
}
并这样称呼它:
context.Stock.LoggingAdd(entity);