确保辛格尔顿通话分贝查询只有一次 [英] Ensure Singleton call db query only once
问题描述
我试图创建一个对象,将负责阅读所有用户访问设置
我创建的类像这样:
公共类设定管理
{
私人静态字符串_connString =
@数据源= MYDB;初始目录= IT;集成安全性= TRUE;异步处理=真;;
私人常量字符串_spName =SettingTest;
私人的IEnumerable<串GT; _mySettings;
私人静态只读懒<&设定管理GT; _instance =新懒人<&设定管理GT;(()=>新建设定管理());
私人设置管理()
{
//Console.WriteLine(\"Hello从构造函数);
如果(_mySettings == NULL)
_mySettings = ReadSettings();
}
公共静态设置管理实例
{
{返回_instance.Value; }
}
公共BOOL CANDO(字符串设定)
{
返回_mySettings.Contains(设置);
}
私人的IEnumerable<串GT; ReadSettings()
{
试
{
使用(VAR康恩=新的SqlConnection(_connString))
{
使用(VAR CMD =新的SqlCommand( ))
{
cmd.Connection =康恩;
cmd.CommandText = _spName;
cmd.CommandType = CommandType.StoredProcedure;
conn.Open();
使用(VAR读卡器= cmd.ExecuteReader())
{
返回reader.Select(SettingParser).ToList();
}
}
}
}
抓
{
}
返回NULL;
}
私人字符串SettingParser(SqlDataReader的R)
{
试
{
的回报 - [R [0]是的DBNull?空,R [0]的ToString();
}
抓
{
}
返回NULL;
}
}
和SqlDataReader的扩展
公共静态类DBExtensions
{
公共静态的IEnumerable< T>选择< T>(
这个SqlDataReader的读者,Func键< SqlDataReader的,T>投影)
{
,而(reader.Read())
{
收益率的回报投影(读者);
}
}
}
然后,我的应用程序中我米可以调用它像这样:
SettingsManager.Instance.CanDo(canWrite)
这将返回true / false值取决于用户的访问级别。
我的问题分别是:结果
-
这是线程安全的?是否有任何机会DB会查询多次吗?如何避免这种情况?
-
我应该用等待和异步?我查询数据库一次。我怎样才能提高呢? (AWAIT和异步真的是新的给我,因为我刚刚从.NET3.5搬到4.5)
1)这是线程安全的?
块引用>
是
有什么没准DB会查询多次吗?
块引用>
没有。
2)如果我使用的await和异步?
块引用>
这将取决于你是否需要你的数据库异步访问。如果你需要,你可以使用异步API ADO.NET
I'm trying to create one object that will be responsible for reading all users access settings.
I've created class as so:
public class SettingsManager { private static string _connString = @"Data Source=MyDB;Initial Catalog=IT;Integrated Security=True;Asynchronous Processing=true;"; private const string _spName = "SettingTest"; private IEnumerable<string> _mySettings; private static readonly Lazy<SettingsManager> _instance = new Lazy<SettingsManager>(() => new SettingsManager()); private SettingsManager() { //Console.WriteLine("Hello from constructor"); if (_mySettings == null) _mySettings = ReadSettings(); } public static SettingsManager Instance { get { return _instance.Value; } } public bool CanDo(string setting) { return _mySettings.Contains(setting); } private IEnumerable<string> ReadSettings() { try { using (var conn = new SqlConnection(_connString)) { using (var cmd = new SqlCommand()) { cmd.Connection = conn; cmd.CommandText = _spName; cmd.CommandType = CommandType.StoredProcedure; conn.Open(); using (var reader = cmd.ExecuteReader()) { return reader.Select(SettingParser).ToList(); } } } } catch { } return null; } private string SettingParser(SqlDataReader r) { try { return r[0] is DBNull ? null : r[0].ToString(); } catch { } return null; } }
And SqlDataReader Extension
public static class DBExtensions { public static IEnumerable<T> Select<T>( this SqlDataReader reader, Func<SqlDataReader, T> projection) { while (reader.Read()) { yield return projection(reader); } } }
Then inside my application I'm able to call it as so:
SettingsManager.Instance.CanDo("canWrite")
this returns true/false value depends on user access level.
My questions are:
Is this thread safe? Are there any chances DB will be query multiple times? How to prevent this?
Should I use await and async? I query db just once. How can I improve this? (await and async are really new to me because I just moved from .NET3.5 to 4.5)
解决方案1) Is this thread safe?
Yes.
Are there any chances DB will be query multiple times?
No.
2) Should I use await and async?
That will depend on whether you need asynchronous access to your database. If you need that you could use the async ADO.NET API.
这篇关于确保辛格尔顿通话分贝查询只有一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!