对Fluent和Nhibernate不熟悉所以也许有一个我在这里看不到的简单问题。以下是我的映射
public class DriverStatusChangeMapping : ClassMap<DriverStatusChange>
{
public DriverStatusChangeMapping()
{
Id(x => x.Id).GeneratedBy.GuidComb();
Map(x => x.CreateReceivedAt);
Map(x => x.RemoveReceivedAt);
Map(x => x.Status);
Component<AuditAction>(x => x.Created, m =>
{
m.Map(x => x.ActionByUser).Column("CreatedByUser");
m.Map(x => x.ActionByUserType).Column("CreatedByUserType");
m.Map(x => x.ActionOccurredAt).Column("CreatedAt");
});
Component<AuditAction>(x => x.Removed, m =>
{
m.Map(x => x.ActionByUser).Column("RemovedByUser");
m.Map(x => x.ActionByUserType).Column("RemovedByUserType");
m.Map(x => x.ActionOccurredAt).Column("RemovedAt");
});
References(c => c.DriverLogEntry)
.Column("DriverLogEntryID")
.Access.Property()
.Cascade.All();
Table("tblDriverStatusChange");
}
}
使用内存测试来验证存储库是否返回了正确的数据。我的RespositoryTestBase如下。
public class RepositoryTestBase : IDisposable
{
private static NHConfiguration.Configuration _configuration;
private static ISessionFactory _sessionFactory;
protected ISession Session { get; set; }
public RepositoryTestBase()
{
_sessionFactory = CreateSessionFactory();
Session = _sessionFactory.OpenSession();
BuildSchema(Session);
}
private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Driver>())
.ExposeConfiguration(cfg => _configuration = cfg)
.BuildSessionFactory();
}
public void BuildSchema(ISession session)
{
var export = new SchemaExport(_configuration);
export.Execute(true, true, false, Session.Connection, null);
}
public void Dispose()
{
Session.Dispose();
}
}
现在,当我按照这样的方式执行get ...时,我有DriverStatusChange记录
_session.Get<DriverStatusChange>(new Guid("6c9b5d4d-986d-4ff7-86ae-a05300d34a8b"));
但如下所示的简单查询总是返回一个空列表。
_session.Query<DriverStatusChange>().Select(d => d).ToList();
以下是我使用RepositoryTestBase
的测试类public class DriverStatusChangeRepositoryTests:RepositoryTestBase
{
private IDriverStatusChangeRepository _driverStatusChangeRepository;
[SetUp]
public void Init()
{
var mockLogger = new Mock<ILogger>();
_driverStatusChangeRepository = new DriverStatusChangeRepository(Session, mockLogger.Object);
}
[TearDown]
public void TearDown()
{
Session.Clear();
}
[TestFixtureTearDown]
public void TestFixtureTearDown()
{
Dispose();
}
[Test]
public void get_where_removed_at_is_null()
{
var driverStatusChanges = CreateDriverStatusChanges(4);
var removedDriverStatusChange = driverStatusChanges[1];
removedDriverStatusChange.Removed = new AuditAction()
{
ActionByUser = "John Doe",
ActionByUserType = "User Type",
ActionOccurredAt = DateTime.UtcNow
};
removedDriverStatusChange.RemoveReceivedAt = DateTime.UtcNow;
_driverStatusChangeRepository.Update(removedDriverStatusChange);
var actual = _driverStatusChangeRepository.GetCurrent(10001, DateTime.MinValue, DateTime.UtcNow).Count;
Assert.AreEqual(3,actual, "Get current did not match");
}
private List<DriverStatusChange> CreateDriverStatusChanges(int number)
{
var driverStatusChanges = new List<DriverStatusChange>();
for (int i = 0; i < number; i++)
{
var driverStatusChange = new DriverStatusChange()
{
Created = GetCreated(i),
CreateReceivedAt = DateTime.UtcNow,
DriverLogEntry = new DriverLogEntry() {CreateReceivedAt = DateTime.UtcNow, Id = Guid.NewGuid(), Driver = new Driver() { DriverID = i+10000}},
Removed = null,
RemoveReceivedAt = null
};
_driverStatusChangeRepository.Add(driverStatusChange);
driverStatusChanges.Add(driverStatusChange);
}
return driverStatusChanges;
}
private AuditAction GetCreated(int number)
{
return
new AuditAction()
{
ActionByUser = "Jane Doe" + number.ToString(CultureInfo.InvariantCulture),
ActionByUserType = "User Type",
ActionOccurredAt = DateTime.UtcNow
};
}
}
答案 0 :(得分:1)
尝试
_session.Query<DriverStatusChange>().ToList();
_session.Query返回一个IQueryable,您可以直接调用'ToList()'。
编辑:(请忽略我上面的愚蠢行为)。
是否因为您的会话在关闭并重新打开之前才能获取记录?我很确定如果会话结束,SQLite InMemory就会丢失。它将在下次读取时重新创建,此时将为空。
解决方案是使用数据库连接提供程序来阻止连接被关闭,这也会阻止InMemory数据库丢失:
public class DatabaseConnectionProviderThatCachesTheConnection : DriverConnectionProvider
{
static IDbConnection _databaseConnection;
public override void CloseConnection(IDbConnection conn)
{
// Deliberately override to do nothing.
}
public override IDbConnection GetConnection()
{
if (_databaseConnection == null)
{
_databaseConnection = base.GetConnection();
}
return _databaseConnection;
}
}
然后你可以在你的会话工厂中使用它:
private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(SQLiteConfiguration
.Standard
.InMemory()
.Raw(Environment.ConnectionProvider,
typeof(DatabaseConnectionProviderThatCachesTheConnection)
.AssemblyQualifiedName)
.ShowSql())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Driver>())
.ExposeConfiguration(cfg => _configuration = cfg)
.BuildSessionFactory();
}
答案 1 :(得分:1)
我没有看到任何交易或Session.Flush
,因此我认为这就是为什么您没有返回任何结果,因为您的更改未提交。在CreateDriverStatusChanges
之后,
_driverStatusChangeRepository.Add(driverStatusChange);
添加
Session.Flush()