I have the following method
public static ProjectListItemViewModel CreateViewModel(P.Project project)
{
return new ProjectListItemViewModel
{
Id = project.Id,
ExpectedResult = Regex.Replace(project.ExpectedResult, #"<[^>]+>| ", string.Empty).Trim().Length > 100 ? Regex.Replace(project.ExpectedResult, #"<[^>]+>| ", string.Empty).Trim().Substring(0, 100) + "..." : Regex.Replace(project.ExpectedResult, #"<[^>]+>| ", string.Empty).Trim(),
Initiator = project.Initiator.FullName,
Status = project.Status.Name,
ProjectManager = project.ProjectManager != null ? project.ProjectManager.FullName :"",
};
}
My question is how to apply Regex to ExpectedResult only if it is not null in the shortest possible way?
I'd change your style a bit, to only execute the regex once:
// Define other methods and classes here
public static ProjectListItemViewModel CreateViewModel(P.Project project)
{
var rex = new Regex(#"<[^>]+>| ");
var expected = rex.Replace(project.ExpectedResult ?? string.Empty, string.Empty).Trim();
return new ProjectListItemViewModel
{
Id = project.Id,
ExpectedResult = expected.Length > 100 ? expected.Length.Substring(0, 100) : expected,
Initiator = project.Initiator.FullName,
Status = project.Status.Name,
ProjectManager = project.ProjectManager != null ? project.ProjectManager.FullName : "",
};
}
Try Like This:
String Result = !ExpectedResult ?? YourRegEx;
In this way It directly applies if the value is not null.
This is not tested
where as this works fine in general c#
String Result = ExpectedResult ?? YourRegEx;
Related
I have 3 classes inherited from same class like
class S1:X{}
class S2:X{}
class S3:X{}
I need to write method to populate List<X> from Sql database. Currently, i am using SqlDataReader to populate. Each class has about 35 properties and db result also about 50K rows. Population is takes too long time. I am curious about the best way to populate large data into List. I am not able to use 3rd party packages because of corporation rules. Is there faster way than SqlDataReader?
Edit:
Modified code sample is below to describe what i am trying. Firstly, may be i should explain some points. SmartSqlReader is inherited from SqlDataReader, AutoMap method is mapper used Reflection.
using(SmartSqlReader reader = db.ExecuteReader(sp)) {
while (reader.Read()) {
bool isFlag1 = reader.GetBool("XX_TO_SEND");
bool isFlag2 = reader.GetBool("YY_TO_SEND");
bool isFlag3 = reader.GetBool("ZZ_TO_SEND");
if (!isFlag1 && !isFlag2 && !isFlag3) {
continue;
}
X x = new X() {
RecordId = reader.GetInt64("RECORD_ID"),
PropCxxx = reader.GetInt64("CXXX"),
PropCxxt = reader.GetInt32("CXXT"),
PropCxxsn = reader.GetString("CXXSN").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("CXXSN"),
PropCxxn = RemoveDiacritics(reader.GetString("CXXSN").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("CXXN").ToLower()),
PropCxxmn = reader.GetString("CXXSN2").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("CXXSN2"),
PropCxxs = reader.GetString("CXXS").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("CXXS"),
Language = reader.GetString("LANGUAGE").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("LANGUAGE"),
PropSxxx = reader.GetString("SXXX").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("SXXX"),
MobilePhone1 = reader.GetString("MobilePhone1").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("MobilePhone1"),
MobilePhone2 = reader.GetString("MobilePhone2").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("MobilePhone2"),
Email1 = reader.GetString("EMAIL1").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("EMAIL1"),
Email2 = reader.GetString("EMAIL2").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("EMAIL2"),
Profile = reader.GetString("PROFILE").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("PROFILE"),
IsPersonnel = reader.GetString("PROFILE") == "XX" ? true : false,
IsPrivateBn = reader.GetString("IsOB").IsNullOrEmptyOrFullSpace() ? false : reader.GetBool("IsOB"),
VIP = reader.GetInt32("VIP_FLAG"),
Gender = reader.GetString("GENDER").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("GENDER"),
BusinessLine = reader.GetString("BUSINESSLINE").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("BUSINESSLINE"),
WorkPhone = reader.GetString("WORK_PHONE").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("WORK_PHONE"),
HomePhone = reader.GetString("HOME_PHONE").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("HOME_PHONE"),
CompanyName = reader.GetString("COMPANY_NAME").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("COMPANY_NAME"),
BranchName = reader.GetString("BRANCH_NAME").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("BRANCH_NAME"),
PfNxxx = reader.GetString("PFNXXX").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("PFNXXX"),
Rgxxx = reader.GetString("RGXXX").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("RGXXX"),
PCBN = reader.GetString("PCBN").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("PCBN"),
BPH = reader.GetString("BPH").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("BPH"),
TranValue = reader.GetString("TRAN_VALUE"),
TranReferenceId = reader.GetString("TRAN_REFERENCE_ID"),
TranReferenceDate = reader.GetDateTime("TRAN_REFERENCE_DATE"),
Amount = reader.GetDecimal("AMOUNT"),
...
DynamicFields = new DynamicFields {
PropCxxx = reader.GetInt64("CXXX"),
FIELD1 = reader.GetString("DYNAMIC_FIELD1"),
FIELD2 = reader.GetString("DYNAMIC_FIELD2"),
FIELD3 = reader.GetString("DYNAMIC_FIELD3"),
FIELD4 = reader.GetString("DYNAMIC_FIELD4"),
FIELD5 = reader.GetString("DYNAMIC_FIELD5"),
FIELD6 = reader.GetString("DYNAMIC_FIELD6"),
FIELD7 = reader.GetString("DYNAMIC_FIELD7"),
FIELD8 = reader.GetString("DYNAMIC_FIELD8"),
FIELD9 = reader.GetString("DYNAMIC_FIELD9"),
FIELD10 = reader.GetString("DYNAMIC_FIELD10"),
FIELD11 = reader.GetString("DYNAMIC_FIELD11"),
FIELD12 = reader.GetString("DYNAMIC_FIELD12"),
FIELD13 = reader.GetString("DYNAMIC_FIELD13"),
FIELD14 = reader.GetString("DYNAMIC_FIELD14"),
FIELD15 = reader.GetString("DYNAMIC_FIELD15")
},
CampaignCodeOrLink = reader.GetString("CAMPAIGN_CODE").IsNullOrEmptyOrFullSpace() ? string.Empty : reader.GetString("CAMPAIGN_CODE"),
ListId = reader.GetInt64("LIST_ID")
};
x.ChannelType = isFlag1 ? Enums.Channel.C1 : isFlag2 ? Enums.Channel.C2 : Enums.Channel.C3;
if (x.ChannelType == Enums.Channel.C1) {
S1 s1 = CommonUtils.AutoMap <S1> (x);
s1.S1Prop = reader.GetString("S1Prop");
xList.Add(s1);
}
else if (x.ChannelType == Enums.Channel.C2) {
S1 s2 = CommonUtils.AutoMap <S2> (x);
s2.S2Prop = reader.GetString("S2Prop");
xList.Add(s2);
} else {
S3 s3 = CommonUtils.AutoMap <S3> (x);
s3.S3Prop = reader.GetString("S3Prop");
xList.Add(s3);
}
}
}
Second Edition:
I just changed object initialization from X x = new X(){...} to
X x;
if(isFlag1)
{
x=new S1();
}
and so on. After that, 80K rows took approximately 10s. It's amazing. In conclusion, when i used CommonUtils.AutoMap method process took ~60m also when i used the second method it decreased to ~10s. This surprised me a lot.
I just changed object initialization method, so i removed CommonUtils.AutoMap that map objects use reflection. After all, 80K rows processed in ~10s instead of ~60m. Here is final code.
using(SmartSqlReader reader = db.ExecuteReader(sp)) {
while (reader.Read()) {
bool isFlag1 = reader.GetBool("XX_TO_SEND");
bool isFlag2 = reader.GetBool("YY_TO_SEND");
bool isFlag3 = reader.GetBool("ZZ_TO_SEND");
if (!isFlag1 && !isFlag2 && !isFlag3) {
continue;
}
X x;
if (isFlag1) {
var s = new S1();
s.S1Prop = reader.GetString("S1Prop");
x = s;
} else if (isFlag2) {
var s = new S2();
s.S2Prop = reader.GetString("S2Prop");
x = s;
} else {
var s = new S3();
s.S3Prop = reader.GetString("S3Prop");
x = s;
}
x.RecordId = reader.GetInt64("RECORD_ID"),
x.PropCxxx = reader.GetInt64("CXXX"),
x.PropCxxt = reader.GetInt32("CXXT"),
...
x.DynamicFields = new DynamicFields {
FIELD1 = reader.GetString("DYNAMIC_FIELD1"),
FIELD2 = reader.GetString("DYNAMIC_FIELD2"),
FIELD3 = reader.GetString("DYNAMIC_FIELD3"),
FIELD4 = reader.GetString("DYNAMIC_FIELD4"),
FIELD5 = reader.GetString("DYNAMIC_FIELD5"),
FIELD6 = reader.GetString("DYNAMIC_FIELD6"),
FIELD7 = reader.GetString("DYNAMIC_FIELD7"),
FIELD8 = reader.GetString("DYNAMIC_FIELD8"),
FIELD9 = reader.GetString("DYNAMIC_FIELD9"),
FIELD10 = reader.GetString("DYNAMIC_FIELD10"),
FIELD11 = reader.GetString("DYNAMIC_FIELD11"),
FIELD12 = reader.GetString("DYNAMIC_FIELD12"),
FIELD13 = reader.GetString("DYNAMIC_FIELD13"),
FIELD14 = reader.GetString("DYNAMIC_FIELD14"),
FIELD15 = reader.GetString("DYNAMIC_FIELD15")
},
};
xList.Add(x);
}
}
I have some data that has values in properties called Poll_1, Poll_2, Poll_3, ...Poll_8.
I need to get a score based on this criteria:
For each Poll_1 thru Poll_4 that is not empty, FirstPollCount is incremented.
For each Poll_5 thru Poll_8 that is not empty, SecondPollCount is incremented.
This is currently how I'm doing it.
int pass1 = 0;
int pass2 = 0;
if (rec.Poll_1.Trim() != "") { pass1++; };
if (rec.Poll_2.Trim() != "") { pass1++; };
if (rec.Poll_3.Trim() != "") { pass1++; };
if (rec.Poll_4.Trim() != "") { pass1++; };
if (rec.Poll_5.Trim() != "") { pass2++; };
if (rec.Poll_6.Trim() != "") { pass2++; };
if (rec.Poll_7.Trim() != "") { pass2++; };
if (rec.Poll_8.Trim() != "") { pass2++; };
aa.FirstPollCount = pass1;
aa.SecondPollCount = pass2;
Is there an easier way to do this?
Not really any better, but if you want to look to an alternative
List<string> firstPolls = new List<string>()
{
rec.Poll_1.Trim(), rec.Poll_2.Trim(),rec.Poll_3.Trim(),rec.Poll_4.Trim()
};
int pass1 = firstPolls.Count(x => x != "");
List<string> secondPolls = new List<string>()
{
rec.Poll_5.Trim(), rec.Poll_6.Trim(),rec.Poll_7.Trim(),rec.Poll_8.Trim()
};
int pass2= secondPolls.Count(x => x != "");
By the way, what is the class for the rec variable? Probably an improvement is to add a internal method that executes this code and returns the value:
int pass1 = rec.GetFirstScoreCount();
int pass2 = rec.GetSecondScoreCount();
thus hiding the implementation details (the Trim() != "") from the client code that uses the rec variable.
You can use Linq:
string s1 = "Random String";
string s2 = "Random String";
string s3 = "Random String";
string s4 = "Random String";
string s5 = "Random String";
string s6 = "";
string s7 = "Random String";
string s8 = "Random String";
int countPool1 = (new List<string>(){s1, s2, s3, s4}).Count(t => t.Trim() != "");
int countPool2 = (new List<string>() { s5, s6, s7, s8 }).Count(t => t.Trim() != "");
Console.Out.WriteLine("Pool 1 : " + countPool1);
Console.Out.WriteLine("Pool 2 : " + countPool2);
With output:
Pool 1 : 4
Pool 2 : 3
You can also use Linq Query Syntax:
List<string> pol1to4Coll = new List<string>() { rec.Poll_1, rec.Poll_2, rec.Poll_3, rec.Poll_4 };
List<string> pol5to8Coll = new List<string>() { rec.Poll_5, rec.Poll_6, rec.Poll_7, rec.Poll_8 };
int countPol1to4Coll = (from poll in pol1to4Coll
where poll != ""
select poll).Count();
int countPol5to8Coll = (from poll in pol5to8Coll
where poll != ""
select poll).Count();
The regex below is not what I exactly need:
Regex.Replace(value.ToString(), "[^0-9a-zA-Z]+", "")
I need to remove escape characters from my string because I am creating one SQL with string and when I have this character ' or this \r\n etc. my Sql generates an error, I cannot use : SqlParameter in this case as I just have a list of SQLs in string, but I can remove the characters that I don't want.
So, I only need to remove these characters:
\r \n ' /\
Added my codes as requested:
private static string ConvertWhetherUsesComas(object value)
{
// formats with comas or not
if (value is String)
{
// fix problem with break characters such as \/`'
value = String.Format("'{0}'", Regex.Replace(value.ToString(), "[^0-9a-zA-Z]+", ""));
}
else if (value is DateTime)
{
value = String.Format("'{0}'", value.SafeToDateTime(null).Value.ToString("yyyy-MM-dd hh:mm:ss tt"));
}
else if (value == null)
{
value = "NULL";
}
else if (value is Boolean)
{
value = value.SafeToBool(false) == false ? 0 : 1;
}
return value.ToString();
}
private static List<String> ConvertDiferencesToSql<T>(Differences<T> differences, string tableName, string primaryKey) where T : IHasId<int>
{
var result = new List<String>();
differences.New.ToList().ForEach(newItem =>
{
var fieldNames = new StringBuilder();
var fieldValues = new StringBuilder();
var properties = newItem.GetType().GetProperties().ToList();
properties.ForEach(f =>
{
var propertyName = f.Name.ToUpper() == "ID" ? primaryKey : f.Name;
var propertyValue = ConvertWhetherUsesComas(f.GetValue(newItem));
if (propertyValue == "NULL") return; // ignores null values
fieldNames.AppendFormat("{0},", propertyName);
fieldValues.AppendFormat("{0},", propertyValue);
});
var sqlFields = fieldNames.ToString(0, fieldNames.Length - 1);
var sqlValues = fieldValues.ToString(0, fieldValues.Length - 1);
result.Add(String.Format("INSERT INTO {0} ({1}) VALUES ({2});", tableName, sqlFields, sqlValues));
});
differences.Changed.ForEach(changedRecord =>
{
var fields = new StringBuilder();
changedRecord.ChangedFields.ForEach(changedField =>
{
var propertyName = changedField.Property == "ID" ? primaryKey : changedField.Property;
var propertyValue = ConvertWhetherUsesComas(changedField.NewValue);
fields.AppendFormat("{0}={1},", propertyName, propertyValue);
});
var sqlFields = fields.ToString(0, fields.Length - 1);
result.Add(String.Format("UPDATE {0} SET {1} WHERE {2}={3};", tableName, sqlFields, primaryKey, changedRecord.Id));
});
differences.Deleted.ForEach(deletedItem => result.Add(String.Format("DELETE FROM {0} WHERE {1}={2};", tableName, primaryKey, deletedItem.GetId())));
return result;
}
You can place these characters into a character class, and replace with string.Empty:
var rgx4 = new Regex(#"[\r\n'/\\]");
var tst = "\r \n ' /\\";
tst = rgx4.Replace(tst, string.Empty);
Result:
A character class usually executes faster, as with alternative list, there is a lot of back-tracking impeding performance.
If I understood correctly, you want something like this :
Regex.Replace(value.ToString(), "(\\\\n|\\\\r|'|\\/\\\\)+", "")
See here.
I'm trying to query a DynamoDB that i have created using code from the Amazon docs with a few simple modifications. I'm trying to take the data i get and write it to a log file as strings. But all i can seem to get is this:
2013-02-22 20:21:37.9268|Trace|[System.Collections.Generic.Dictionary2+KeyCollection[System.String,Amazon.DynamoDB.Model.AttributeValue] System.Collections.Generic.Dictionary2+ValueCollection[System.String,Amazon.DynamoDB.Model.AttributeValue]]|
I've tried a few different things but all return either the same thing, or something very similar.
The code i'm using:
private static void GetCallsForRange()
{
AmazonDynamoDBConfig config = new AmazonDynamoDBConfig();
config.ServiceURL = "http://dynamodb.us-west-2.amazonaws.com";
AmazonDynamoDBClient client = new AmazonDynamoDBClient(config);
DateTime startDate = DateTime.Today.AddDays(-21);
string start = startDate.ToString("G", DateTimeFormatInfo.InvariantInfo);
DateTime endDate = DateTime.Today;
string end = endDate.ToString("G", DateTimeFormatInfo.InvariantInfo);
QueryRequest request = new QueryRequest
{
TableName = "Inquiry",
HashKeyValue = new AttributeValue { S = "+15555555555" },
RangeKeyCondition = new Condition
{
ComparisonOperator = "BETWEEN",
AttributeValueList = new List<AttributeValue>()
{
new AttributeValue { S = start },
new AttributeValue { S = end }
}
}
};
QueryResponse response = client.Query(request);
QueryResult result = response.QueryResult;
foreach (Dictionary<string, AttributeValue> item in response.QueryResult.Items)
{
string logMsg = String.Format("[{0} {1}]", item.Keys, item.Values);
Logging.LogTrace(logMsg);
}
}
You will need to iterate over each item in the response.QueryResult.Items. You could rewrite your loop like this (taken from the Amazon DynamoDB documentation):
foreach (Dictionary<string, AttributeValue> item in response.QueryResult.Items)
{
LogItem(item);
}
private void LogItem(Dictionary<string, AttributeValue> attributeList)
{
foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
{
string attributeName = kvp.Key;
AttributeValue value = kvp.Value;
string logValue =
(value.S == null ? "" : value.S) +
(value.N == null ? "" : value.N.ToString()) +
(value.B == null ? "" : value.B.ToString()) +
(value.SS == null ? "" : string.Join(",", value.SS.ToArray())) +
(value.NS == null ? "" : string.Join(",", value.NS.ToArray())) +
(value.BS == null ? "" : string.Join(",", value.BS.ToArray()));
string logMsg = string.Format("[{0} {1}]", attributeName, logValue);
Logging.LogTrace(logMsg);
}
}
Essentially, you need to discover the "type" of the AttributeValue(String, Number, Binary, StringSet, NumberSet, BinarySet) and then output that to your log.
I hope that helps!
With some earlier help, I created a C# script in SSIS to retrieve data from MongoDB to SQL Server. While regular documents are retrieved easily, nested documents and arrays are problematic.
Problem 1: I have shipping_address.country that returns results by using
this.UserDBBuffer.SCountry = document["shipping_address"].AsBsonDocument["country"].ToString();
However, mlocation.address gives me an error '"country" not found' using the same code:
this.UserDBBuffer.Country = document["mlocation"].AsBsonDocument["country"].ToString();
Problem 2: Retrieving items from arrays. I have an array that looks like "devices -> Document -> device_data -> model" or "devices -> Document -> device_data -> brand". How do I retrieve "model" or "brand" values in my code?
Thanks a lot for your help. Below is my entire code:
public override void CreateNewOutputRows()
{
string connectionString = "mongodb://localhost";
MongoServer myMongo = MongoServer.Create(connectionString);
myMongo.Connect();
var db = myMongo.GetDatabase("UserDB");
//Declaring variables for Date Created conversions
string DateCreatedString;
DateTime DateCreatedDateUTC;
DateTime DateCreatedDateLocal;
var fields = Fields.Include("mlocation.country", "mlocation", "_id", "primary_email", "gender", "date_created");
var collection = db.GetCollection<BsonDocument>("users");
foreach (var document in collection.FindAll().SetFields(fields))
{
this.UserDBBuffer.AddRow();
this.UserDBBuffer.ID = document["_id"] == null ? "" : document["_id"].ToString();
this.UserDBBuffer.Country = document["mlocation"].AsBsonDocument["country"].ToString();
this.UserDBBuffer.PrimaryEmail = document["primary_email"] == null ? "" : document["primary_email"].ToString();
this.UserDBBuffer.Gender = document["gender"] == null ? "" : document["gender"].ToString();
//Importing Date Created as String for data manipulation
DateCreatedString = document["date_created"] == null ? "" : document["date_created"].ToString();
//First, making sure that we have a UTC datetime
DateCreatedDateUTC = DateTime.Parse(DateCreatedString).ToUniversalTime();
//Second, converting to Local Time
DateCreatedDateLocal = DateTime.Parse(DateCreatedString).ToLocalTime();
//Finally, assigning variables to rows
this.UserDBBuffer.DateTimeCreatedUTC = DateCreatedDateUTC;
this.UserDBBuffer.DateTimeCreatedLocal = DateCreatedDateLocal;
}
myMongo.Disconnect();
}
For Problem 2, I found a Java Script that someone used; if I can convert it to C#, it might help a lot:
count = 0;
function user_list(){
var cursor = db.users.find()
//var cursor = db.users.find({"devices": {"$ne":[]}})
cursor.forEach(function(user) {
var deviceInfo = "";
if (user.devices){
if (user.devices[0]){
dd = user.devices[0].device_data;
if (dd) {
deviceInfo = dd.model + "," + dd.brand + "," + dd.model + "," + dd.device + "," + dd.pixel_height + "," + dd.pixel_width + "," + dd.pixel_format;
}
}
}
var location = "";
if (user.mlocation) location = user.mlocation.country;
print(user._id + "," + location + "," + user.primary_email + "," + user.date_created + "," + deviceInfo);
count++;
});
}
user_list();
print(count);
For problem 1, are you sure all docs contain a field mlocation that is a document containing the country field. I was able to reproduce the "Element country not found" with a document that is missing the value.
e.g. with
db.users.find()
{ "_id" : ObjectId("4f04c56a0f8fa4413bed1078"), "primary_email" : "email#email.com", "shipping_address" : [ {"country" : "USA", "city" : "San Francisco" }, { "country" : "IN", "city" : "Chennai" } ], "mlocation" : { "country" : "Canada", "city" : "Montreal" } }
{ "_id" : ObjectId("4f04d1605ab5a3805aaa8666"), "primary_email" : "incorrect#email.com", "shipping_address" : [ { "country" : "MX", "city" : "Cabo San Lucas" } ], "mlocation" : { "city" : "Montreal" } }
the 2nd document throws the exception. You can either check for its existance or use the default value option
document["mlocation"].AsBsonDocument.GetValue("country", null)
For problem 2, you cannot cast a BsonArray as a document. So for the above e.g to get shipping_address.country you can do something like
foreach (var addr in document["shipping_address"].AsBsonArray)
{
var country = addr.AsBsonDocument["country"].AsString;
}
Assuming the devices element is an array, just drill your way down into the element you are looking for, like this:
BsonDocument document; // assume this comes from somewhere
var devices = document["devices"].AsBsonArray;
var device = devices[0].AsBsonDocument; // first element of array
var deviceData = device["device_data"].AsBsonDocument;
var model = deviceData["model"].AsString;
var brand = deviceData["brand"].AsString;
I've broken it down into steps for clarity, but you can combine some of these steps into longer statements if you want.
To clarify your comment to Robert's answer, you can use BsonDocument.Contains to check if a given BsonDocument contains a field of the specified name before getting its value (http://api.mongodb.org/csharp/current/html/6181f23f-f6ce-fc7d-25a7-fc682ffd3c04.htm)
Instead of:
var mlocation = document["mlocation"].AsBsonDocument;
var country = "";
if (mlocation != null && mlocation.Contains("country"))
{
country = mlocation.AsBsonDocument.GetValue("country").ToString();
}
I would write:
var mlocation = document["mlocation"].AsBsonDocument;
var country = "";
if (mlocation.Contains("country"))
{
country = mlocation["country"].AsString;
}
And instead of:
var devices = document["devices"].AsBsonArray;
if (devices.ToList().Count > 0)
{
if (devices[0].AsBsonDocument != null)
{
var deviceinfo = devices[0].AsBsonDocument;
if (deviceinfo["device_data"].AsBsonDocument != null)
{
var deviceData = deviceinfo["device_data"].AsBsonDocument;
model = deviceData.GetValue("model", null).AsString;
}
}
}
I would write:
var devices = document["devices"].AsBsonArray;
if (devices.Count > 0)
{
var deviceinfo = devices[0].AsBsonDocument;
if (deviceinfo.Contains("device_data"))
{
var deviceData = deviceinfo["device_data"].AsBsonDocument;
var model = deviceData.GetValue("model", "").AsString; // "" instead of null
}
}