I'm mapping up data from an SQL database into an object in c#. The problem is, one of the columns is unfortunately named "100_hrs". So when I am making my C# object, I get an error in the declaration:
public float 100_hrs {get; set;}
I've tried using # in front but it does not work. If the property is not named the same as the table column, then it does not map up. How can I map this up?
You can use column attribute as below
[Column("100_hrs")]
public float hundred _hrs {get; set;}
MSDN
MVC3 naming a column beginning with a number
Answering why the # didn't work.
# lets you declare variables with keywords names, it doesn't allow you to use invalid tokens.
MSDN
Regarding to the main question, it seems like you should change the table column name.
If you're using some sort of mapping engine like NHibernate of EntityFramework, you can change the mapping file. Example:
[Column("100_hrs")]
public float hrs100 {get; set;}
Why not use underscore before the number say _100_hrs since you could easily manipulate it by string extraction if you want to map it to your column? Although there is a little overhead it sure solve your problem.
Related
I need to store a standard record structure in a template file that can be loaded in by a c# program. The record structure relates to a new entry in a database.
Each new entry has:
- a header which has a list of values for that table, and
- a list of items that link to the new entry
Now, here's the tricky part.
- Each item can itself have a list of sub-items (that are all item type)
The program should load in the template, create a new record, and then process each item one at a time. If the item contains a list of sub-items, those will be processed before the parent item is completed.
I was thinking I could perhaps achieve this using JSON?
I will not give you code for doing this but may be enough pointers.
Design the Class that should represent your Record. Ex:
If my record is that of an Employee
public class Employee
{
public string Name {get; set;}
public string EmpId {get; set;}
public Link<Jobs> JobHistory {get; set;}
}
Read about Serializers. Using them you can convert objects to Binary, Xml, Json etc. formats. So this is key for getting the state/stuff that needs to be persisted.
Read about File handling stuff in System.IO. File.Write/Read methods. Also, how to use these along with Serializers (may need to read on MemoryStream/StreamReader/Writers etc). This will help you write the persistable state into file system.
Thanks Prateek Shrivastava,
Lists was the solution I was looking for.
I tried storing the data as JSON, but worked out better to create a few additional tables in the database, and write an app to create and edit templates.
Using JSON.NET for the serialisation and deserialisation.
Is it possible to add new datatypes to the existing DataAnnotations (I'm not looking for a validator but a raw data type). For example
Currnetly you have
[DataType(DataType.Html)]
public string Footer {get; set;}
And into the mix you can add ~Views/Shared/EditorTemplates/Html.cshtml
I'd like to be able to add [DataType(DataType.CSS)] I know in theory I could use a UIHint for adding a specific view, but if possible I'd like to do it at an even earlier stage and specify the datatype rather than relying on UI Hints.
Any pointers would be greatly appreciated. A Quick search of S.O seems a lot of answers around Custom meta-data types, custom validators, and multiple datatyps but I can't seem to find one for adding a new core data-type.
DataType has a second constructor that takes a string. However, internally, this is actually the same as using the UIHint attribute.
Adding a new core DataType is not possible since the DataType enumeration is part of the .NET framework. The closest thing you can do is to create a new class that inherits from the DataTypeAttribute. Then you can add a new constructor with your own DataType enumeration.
public NewDataTypeAttribute(DataType dataType) : base(dataType) { }
public NewDataTypeAttribute(NewDataType newDataType) : base (newDataType.ToString()) { }
Yes, you can. DataTypeAttribute has a constructor that accepts string.
I'm researching MongoDB at the moment. It's my understanding that the official C# driver can perform serialization and deserialization of POCOs. What I haven't found information on yet is how a reference between two objects is serialized. [I'm talking about something that would be represented as two seperate documents, with ID links, rather than embeded documents.
Can the serialization mechanism handle this kind of situation? (1):
class Thing {
Guid Id {get; set;}
string Name {get; set;}
Thing RelatedThing {get; set;}
}
Or do we have to sacrifice some OOP, and do something like this? (2) :
class Thing {
Guid Id {get; set;}
string Name {get; set;}
Guid RelatedThing_ID {get; set;}
}
UPDATE:
Just a couple of related questions then...
a) If the serializer is able to handle situation (1). What is an example of how to do this without using embedding?
b) If using embedding, would it be possible to query across all 'Things' regardless of whether they were 'parents' or embedded elements? How would such a query look like?
The C# driver can handle serializing the class containing a reference to another instance of itself (1). However:
As you surmised, it will use embedding to represent this
There must be no circular paths in the object graph or a stack overflow will occur
If you want to store it as separate documents you will have to use your second class (2) and do multiple inserts.
Querying across multiple levels is not really possible when the object is stored as one large document with nested embedding. You might want to look at some alternatives like:
https://docs.mongodb.com/manual/applications/data-models-tree-structures/
Yes, That is completely possible.
One thing you must understand about MongoDB and most NoSQL solutions is that objects can be contained within other objects. In the case of MongoDB, it's basically, if you can create the object in JSON, then you can create the object in MongoDB.
In general, you should strive to have a "relatively" denormalized database structure. A little bit of duplicated data is ok as long as you're not updating it often.
If you really want a reference to another document, you can use a DBRef. However there is limitation with references in MongoDB.
you can only query by id on a ref
when you get your Thing's document, you'll have to make a second query to get the associated RelatingThing's document as join doesn't exists in MongoDB.
I've encountered the same issue recently, and I usually steer away from them but... I'm thinking that this could be a good use for a significant numbering system deployed on the Id field.
class Thing {
string Id {get; set;}
string Name {get; set;}
string RelatedThing {get; set;}}
So, simplifying, if Id was something like "T00001" (or indeed T + GUID), you could easily get the set of things from Mongo by querying for something like Id starts with T, and setting up objects for them all (or just for the subset you know contains your reference, if it is a very large set).
You know/expect that RelatedThing to be a Thing, but it will just be a string when it comes back from Mongo. But if you've set up objects as above, you could effectively use the string as if it were an object reference (after all, that is what it really is, done kind of "manually").
Its a 'loose' way of doing it, but might be workable for you.
Can anyone see any pitfalls with that approach?
I searching a way to map the Bson objects defined using readable names ("category") to shorts names ("ct") and limit the space occuped by the items names in the main document base. I have seen this using others Drivers but what about using official Driver. How i can make, where is the best place to define. Can use longnames in queries and retrieve short contents?.
thanks.
Since nobody has actually given the answer to the question, here it is.
With the official driver you can do this by decorating a property name with BsonElement. For example:
public class SomeClass
{
public BsonObjectId Id { get; set; }
[BsonElement("dt")]
public DateTime SomeReallyLongDateTimePropertyName { get; set; }
}
Now the driver will use "dt" as the BSON property name.
However, at this time there is no way to query using the POCO property name. You would need to use "dt" in your queries. There is a separate project that is built on top of the C# driver that provides LINQ style querying capabilities, but I have not tested it to verify if it will do what you are asking.
It's better to keep models clean. And MongoDB.Driver allows to do it outside.
BsonClassMap.RegisterClassMap<SomeClass>(x =>
{
x.AutoMap();
x.GetMemberMap(m => m.SomeReallyLongDateTimePropertyName).SetElementName("dt");
});
Consider a record
{ last_name : "Smith", best_score: 3.9 }
The strings "last_name" and "best_score" will be stored in each object's BSON. Using shorter strings would save space:
{ lname : "Smith", score : 3.9 }
Would save 9 bytes per document. This of course reduces expressiveness to the programmer and is not recommended unless you have a collection where this is of significant concern.
Field names are not stored in indexes as indexes have a predefined structure. Thus, shortening field names will not help the size of indexes. In general it is not necessary to use short field names.
check source for more details
but other side is described in famous topic "You saved 5 cents, and your code is not readable, congrats!"
And my own opinion that short name is bad way.
This question arose when I was trying to figure out a larger problem that, for simplicity sake, I'm omitting.
I have to represent a certain data structure in C#. Its a protocol that will be used to communicate with an external system. As such, it has a sequence of strings with predefined lengths and integer (or other, more complicated data). Let's assume:
SYSTEM : four chars
APPLICATION : eight chars
ID : four-byte integer
Now, my preferred way to represent this would be using strings, so
class Message
{
string System {get; set; }; // four characters only!
string Application {get; set; }; // eight chars
int Id {get; set; };
}
Problem is: I have to ensure that string doesn't have more than the predefined length. Furthermore, this header will actually have tenths of fields, are those will change every now and then (we are still deciding the message layout).
How is the best way to describe such structure? I thought, for example, to use a XML with the data description and use reflection in order to create a class that adheres to the implementation (since I need to access it programatically).
And, like I said, there is more trouble. I have other types of data types that limits the number of characters/digits...
For starters: the whole length issue. That's easily solved by not using auto-properties, but instead declaring your own field and writing the property the "old-fashioned" way. You can then validate your requirement in the setter, and throw an exception or discard the new value if it's invalid.
For the changing structure: If it's not possible to just go in and alter the class, you could write a solution which uses a Dictionary (well, perhaps one per data type you want to store) to associate a name with a value. Add a file of some sort (perhaps XML) which describes the fields allowed, their type, and validation requirements.
However, if it's just changing because you haven't decided on a final structure yet, I would probably prefer just changing the class - if you don't need that sort of dynamic structure when you deploy your application, it seems like a waste of time, since you'll probably end up spending more time writing the dynamic stuff than you would altering the class.