在C#中存储永不改变的静态数据的最佳方法是什么

时间:2010-05-25 18:08:02

标签: c# asp.net-mvc

我有一个在asp.net c#应用程序中存储数据的类,它永远不会改变。我真的不想把这些数据放在数据库中 - 我希望它留在应用程序中。这是我在应用程序中存储数据的方法:

public class PostVoteTypeFunctions
{
    private List<PostVoteType> postVotes = new List<PostVoteType>();
    public PostVoteTypeFunctions()
    {
        PostVoteType upvote = new PostVoteType();
        upvote.ID = 0;
        upvote.Name = "UpVote";
        upvote.PointValue = PostVotePointValue.UpVote;
        postVotes.Add(upvote);

        PostVoteType downvote = new PostVoteType();
        downvote.ID = 1;
        downvote.Name = "DownVote";
        downvote.PointValue = PostVotePointValue.DownVote;
        postVotes.Add(downvote);

        PostVoteType selectanswer = new PostVoteType();
        selectanswer.ID = 2;
        selectanswer.Name = "SelectAnswer";
        selectanswer.PointValue = PostVotePointValue.SelectAnswer;
        postVotes.Add(selectanswer);

        PostVoteType favorite = new PostVoteType();
        favorite.ID = 3;
        favorite.Name = "Favorite";
        favorite.PointValue = PostVotePointValue.Favorite;
        postVotes.Add(favorite);

        PostVoteType offensive = new PostVoteType();
        offensive.ID = 4;
        offensive.Name = "Offensive";
        offensive.PointValue = PostVotePointValue.Offensive;
        postVotes.Add(offensive);

        PostVoteType spam = new PostVoteType();
        spam.ID = 0;
        spam.Name = "Spam";
        spam.PointValue = PostVotePointValue.Spam;
        postVotes.Add(spam);
    }
}

当调用构造函数时,运行上面的代码。我有一些函数可以查询上面的数据。但这是在asp.net中存储信息的最佳方式吗?如果不是你会推荐什么?

8 个答案:

答案 0 :(得分:3)

这是一个不可变结构的候选者,“ 看起来像 ”一个枚举: (另外,我注意到你为其中两个使用了相同的id值,所以我修复了...... 您可以像使用枚举一样使用以下内容...

PostVoteTypeFunctions myVar = PostVoteTypeFunctions.UpVote;

并且真正的好处是这种方法不需要4字节整数以外的实例存储(它将存储在堆栈中,因为它是一个结构)。所有硬编码值都存储在类型本身中......每个AppDomain只存在一个...

public struct PostVoteTypeFunctions 
{ 
    private int id;
    private bool isDef;
    private PostVoteTypeFunctions ( )  { } // private to prevent direct instantiation
    private PostVoteTypeFunctions(int value) { id=value; isDef = true; }

    public bool HasValue { get { return isDef; } }
    public bool isNull{ get { return !isDef; } }
    public string Name 
    { 
       get 
       {  return 
             id==1? "UpVote":
             id==2? "DownVote":
             id==3? "SelectAnswer":
             id==4? "Favorite":
             id==5? "Offensive":
             id==6? "Spam": "UnSpecified";
       }
    }
    public int PointValue 
    { 
       get 
       {  return // Why not hard code these values here as well  ?
             id==1? PostVotePointValue.UpVote:
             id==2? PostVotePointValue.DownVote
             id==3? PostVotePointValue.SelectAnswer:
             id==4? PostVotePointValue.Favorite:
             id==5? PostVotePointValue.Offensive:
             id==6? PostVotePointValue.Spam: 
                    0;
       }
    }
    // Here Add additional property values as property getters 
    // with appropriate hardcoded return values using above pattern

    // following region is the static factories that create your instances,
    //  .. in a way such that using them appears like using an enumeration
    public static PostVoteTypeFunctions UpVote = new PostVoteTypeFunctions(1);
    public static PostVoteTypeFunctions DownVote= new PostVoteTypeFunctions(2);
    public static PostVoteTypeFunctions SelectAnswer= new PostVoteTypeFunctions(3);
    public static PostVoteTypeFunctions Favorite= new PostVoteTypeFunctions(4);
    public static PostVoteTypeFunctions Offensive= new PostVoteTypeFunctions(5);
    public static PostVoteTypeFunctions Spam= new PostVoteTypeFunctions(0);       
} 

答案 1 :(得分:1)

很难从您发布的代码片段中判断出是否公开了该类之外的任何数据。

如果没有,那么这将有效。但是,如果没有,有几个问题:

  • 如果您要公开列表,则只能使用IEnumerable<PostVoteType>关键字将其副本作为yield返回。
  • 确保您的PostVoteType是不可变的,否则可以更改引用并且可能会更改使用的字段

答案 2 :(得分:1)

“从不”确实是一个非常难的词。

在您的特定情况下,您断言您的PostVoteType数据不仅绝对且不可变,而且容器集合也是如此。坦率地说,我不相信你可以知道,因为你不是生意(你对要求的解释是不完美的)而你并不是通灵的(你对未来的了解并不完美)。

我建议您始终在某种的存储库中存储任何无法表示为枚举的数据。你期望关系和/或事务和/或可变需求意味着数据库,如果你期望高读写比率可以是一个配置文件(我认为这应该是)。

编辑:就内存持久性而言,我同意其他人认为缓存是存储它的最佳位置,或者更确切地说是缓存支持的域对象。


除此之外:你构建的PostVoteTypes非常糟糕 - 强烈建议你想要一个重构器:)

答案 3 :(得分:1)

查看您的代码,看起来您只是想创建一组实际上只是将枚举PostVotePointValue放入某​​种列表的对象。即你已经拥有了你需要在enum本身定义的内容。我鼓励你不要在两个地方定义相同的信息(你要求的这个数据存储和枚举)。这是我看到人们常犯的错误。他们创建一个查找表/列表,然后创建一个镜像表行的枚举,这意味着他们必须修改两个位置才能对列表进行任何更改。

如果PostVotePointValue不是枚举,而只是一些常量,或者如果有更多信息要计划打包,那么这是不相关的。

以下是一些如何使用http://www.csharp-station.com/Tutorials/Lesson17.aspx

将枚举作为“列表”的示例
   // iterate through Volume enum by name
    public void ListEnumMembersByName()
    {
        Console.WriteLine("\n---------------------------- ");
        Console.WriteLine("Volume Enum Members by Name:");
        Console.WriteLine("----------------------------\n");

        // get a list of member names from Volume enum,
        // figure out the numeric value, and display
        foreach (string volume in Enum.GetNames(typeof(Volume)))
        {
            Console.WriteLine("Volume Member: {0}\n Value: {1}",
                volume, (byte)Enum.Parse(typeof(Volume), volume));
        }
    }

    // iterate through Volume enum by value
    public void ListEnumMembersByValue()
    {
        Console.WriteLine("\n----------------------------- ");
        Console.WriteLine("Volume Enum Members by Value:");
        Console.WriteLine("-----------------------------\n");

        // get all values (numeric values) from the Volume
        // enum type, figure out member name, and display
        foreach (byte val in Enum.GetValues(typeof(Volume)))
        {
            Console.WriteLine("Volume Value: {0}\n Member: {1}",
                val, Enum.GetName(typeof(Volume), val));
        }
    }
}

您应该能够将上述内容改编为一种方法,该方法将为您提供一个列表,您可以根据需要使用该列表进行数据绑定。

答案 4 :(得分:1)

我想知道为什么你不能只使用一个简单的枚举?

public enum PostVoteType
{
    UpVote = 0,
    DownVote = 1,
    SelectAnswer = 2,
    Favorite = 3,
    Offensize = 4,
    Spam = 5
}

答案 5 :(得分:0)

如果它没有改变,通常被访问,并且对所有用户都是一样的,那么.NET缓存就是合适的地方。有一个产生这些值的属性。在内部,属性检查此列表的缓存并返回存储的值;否则,它从头开始构造它,添加到缓存中,并返回值。

尽管如此,即使您将其缓存,仍应在数据库中进行配置。我想你需要将这些值与数据库中的其他数据结合使用。

答案 6 :(得分:0)

当您需要经常访问相同的数据,并且不需要将其存储到底层数据库中,并且该数据在应用程序可能遇到的每种情况下大致相同时,我建议使用缓存。缓存源于这些要求。缓存通常是提供数据的最快方式,因为它们始终保存在内存中或类似于易用性,并且使应用程序更容易访问。

以下是Microsoft Enterprise Library提供的一个很好的缓存工具,Caching Application Block

我认为花时间学习如何有效地使用它是值得的。

答案 7 :(得分:-1)

创建一个单例类。