I have the following system: a "mother" class called DataClass, has properties and two of them are classes, PartClass and MemberClass. In particular, MemberClass has properties and one of them is a class, SideClass - with its own properties.
Here is the code sample:
using System;
namespace ConsoleApp
{
public class DataClass
{
public int num { get; set; }
public string code { get; set; }
public PartClass part { get; set; }
public MemberClass member { get; set; }
public DataClass()
{
PartClass part = new PartClass();
MemberClass member = new MemberClass();
}
}
public class PartClass
{
public int seriesNum { get; set; }
public string seriesCode { get; set; }
public PartClass() { }
}
public class MemberClass
{
public int versionNum { get; set; }
public SideClass side { get; set; }
public MemberClass()
{
SideClass side = new SideClass();
}
}
public class SideClass
{
public string firstDetail { get; set; }
public string secondDetail { get; set; }
public bool include { get; set; }
public SideClass() { }
}
Now, I am trying to initialize the DataClass and assign values to all properties, and this doesn't work.
So, the DataClass "owns" the PartClass and the MemberClass and the MemberClass itself "sees" the SideClass which is the bottom class and sort of independent of all.
Here the rest of code:
class Program
{
static void Main(string[] args)
{
DataClass myData = new DataClass()
{
num = 13,
code = "message",
//from here downwards nothing works; error..
part.seriesNum = 1,
part.seriesCode = 7,
member.versionNum = 9,
member.side.firstDetail = "pass",
member.side.secondDetail = "checked",
member.side.include = true;
}
}
}
I thought that by installing constructors and properties the DataClass instantiation would not have problems, but actually the DataClass does not see any non-trivial properties (properties referring to classes).
Could someone help me please? Thank you..
Use following :
DataClass myData = new DataClass()
{
num = 13,
code = "message",
part = new PartClass()
{
seriesNum = 1,
//here down nothing works; error
seriesCode = "abc"
},
member = new MemberClass()
{
versionNum = 9,
side = new Side()
{
firstDetail = "pass",
secondDetail = "checked",
include = true
}
}
};
To not have to create the instance of Member Class and Part Class manually every time, you can create the instances using get and set methods.
public class DataClass
{
public int num { get; set; }
public string code { get; set; }
private PartClass _part;
public PartClass part { get { if (_part == null) _part = new PartClass(); return _part; } set { _part = value; } }
private MemberClass _member;
public MemberClass member { get { if (_member == null) _member = new MemberClass(); return _member; } set { _member = value; } }
}
you should create an instance of DataClass then initialize fields
DataClass myData = new DataClass();
myData.num = 13,
myData.code = "message",
myData.part.seriesNum = 1,
myData.part.seriesCode = 7,
myData.member.versionNum = 9,
myData.member.side.firstDetail = "pass",
myData.member.side.secondDetail = "checked",
myData.member.side.include = true;
Related
I'm trying to create a property class with a default value and no value. Is this right? If I want a property with no value I'll just call GameLevel class and if I want a property with default value I'll just call GameLevelWithDefaultValue
public abstract class GameLevel
{
public abstract int nextLevelToUnlock { get; set; }
public abstract List<LevelDetails> levelDetails { get; set; }
}
class GameLevelWithDefaultValue : GameLevel
{
public override int nextLevelToUnlock { get; set; } = 1;
public override List<LevelDetails> levelDetails { get; set; } = new List<LevelDetails>()
{
new LevelDetails{levelIndex = 1, Stars = 0 },
new LevelDetails{levelIndex = 2, Stars = 0 },
new LevelDetails{levelIndex = 3, Stars = 0 }
};
}
public class LevelDetails
{
public int levelIndex { get; set; }
public int Stars { get; set; }
}
I meant something like this:
public class GameLevel
{
public int NextLevelToUnlock { get; set; }
public List<LevelDetails> LevelDetails { get; set; }
public GameLevel() { }
public GameLevel(int nextLevelToUnlock, List<LevelDetails> levelDetails)
{
NextLevelToUnlock = nextLevelToUnlock;
LevelDetails = levelDetails;
}
}
public class LevelDetails
{
public int LevelIndex { get; set; }
public int Stars { get; set; }
public LevelDetails(int levelIndex, int stars)
{
LevelIndex = levelIndex;
Stars = stars;
}
}
public static class GameLevelBuilder
{
public static GameLevel BuildGameLevelWithDefaultValue()
{
var defaultLevelDetail = new List<LevelDetails>()
{
new LevelDetails(1, 0),
new LevelDetails(2, 0),
new LevelDetails(3, 0)
};
return new GameLevel(1, defaultLevelDetail);
}
}
When you need the object with the default value, you'll let the GameLevelBuilder create the object for you, while when you need the object without passing the initial values, you'll use the parameterless constructor of GameLevel.
You cannot instantiate an abstract class. If you inherit an abstract class, you must override it's abstract properties. So, the value of nextLevelToUnlock and levelDetails depends on the child class.
Also, default value for class in C# is null, or the result of it's zero parameter constructor for value types. If you don't assign any value to a field, it will get it's default value.
Concering the following class:
public partial class ByValueCondition
{
public ParameterCondition ParameterCondition { get; set; }
public TimeOfDayCondition TimeOfDayCondition { get; set; }
public SimulationTimeCondition SimulationTimeCondition { get; set; }
public StoryboardElementStateCondition StoryboardElementStateCondition { get; set; }
public UserDefinedValueCondition UserDefinedValueCondition { get; set; }
public TrafficSignalCondition TrafficSignalCondition { get; set; }
public TrafficSignalControllerCondition TrafficSignalControllerCondition { get; set; }
}
I want a customization in autofixture that will randomly only choose one property and fill it, while leaving the other ones blank. The configuration of the underlying classes should be still defined by the global customizations of the fixture.
Also it should be possible to create a Collection of ByValueCondition.
I tried around with this but cant find an easy solution except creating a ISpecimenbuilder from the ground up.
I would personally do it with following schema:
// Interface implemented by all Conditions
public interface ICondition
{
bool IsConditionTrue(object ObjectThatWeKnow);
}
// Your object
public partial class ByValueCondition
{
public ICondition Condition { get; set; }
}
// And here you define all types of conditions
public class ParameterCondition : ICondition
{
public object Parameter { get; set; }
public bool IsConditionTrue(object ObjectThatWeKnow)
{
return ObjectThatWeKnow.Equals(Parameter);
}
}
public class TimeOfDayCondition : ICondition
{
public bool IsConditionTrue(object ObjectThatWeKnow) { return true; }
}
public class SimulationTimeCondition : ICondition
{
public bool IsConditionTrue(object ObjectThatWeKnow) { return true; }
}
And the randomness you could do as:
var conditions = new List<ICondition>()
{
new ParameterCondition() { Parameter = "whatever" },
new ParameterCondition() { Parameter = "otherString" },
new ParameterCondition() { Parameter = "NextOne" },
new TimeOfDayCondition() { TimeBefore = DateTime.Now },
new TimeOfDayCondition() { TimeAfter = DateTime.Now.AddDays(-1) },
}
var rand = new Random();
var randomN = rand.Next(0, conditions.Count);
var byValueCondition = new ByValueCondition();
byValueCondition.Condition = conditions[randomN]; //Here you assign random value
I've followed the nested example from the Automapper Wiki but I'm having some trouble extending it. In the code below, I'm trying to map InnerDest2 to OuterSource. Specifically, I want InnerDest2.Value to be populated with OuterSource.Value but when I run, InnerDest2 comes back as null. I'm sure there is something simple I'm missing, but I just can't figure it out.
Any ideas?
namespace AutomapNestTest
{
class Program
{
static void Main(string[] args)
{
ConfigureAutomapper();
var source = new OuterSource
{
Value = 5,
Inner = new InnerSource { OtherValue = 15 },
};
var dest = new OuterDest();
AutoMapper.Mapper.Map(source, dest);
}
private static void ConfigureAutomapper()
{
AutoMapper.Mapper.Initialize(cfg =>
{
cfg.CreateMap<OuterSource, OuterDest>();
cfg.CreateMap<InnerSource, InnerDest>();
cfg.CreateMap<OuterSource, InnerDest2>();
});
}
}
public class OuterSource
{
public int Value { get; set; }
public InnerSource Inner { get; set; }
}
public class InnerSource
{
public int OtherValue { get; set; }
}
public class OuterDest
{
public int Value { get; set; }
public InnerDest Inner { get; set; }
public InnerDest2 Inner3 { get; set; }
}
public class InnerDest
{
public int OtherValue { get; set; }
}
public class InnerDest2
{
public int Value { get; set; }
}
}
You are mapping an OuterSource object to an OuterDesc object. There is a mapping configuration from OuterSource to InnerDest2 but there is no property of type OuterSource inOuterSource itself so there is no way for the propertyInner3 in OuterDest to be mapped from anything.
If you need the source.Value to be mapped to dest.Inner3.Value, you would have to do another mapping explicitly. First declare the variable:
var innerDest2 = new InnerDest2();
After this, do the mapping and set the dest.Inner3:
AutoMapper.Mapper.Map(source, innerDest2);
dest.Inner3 = innerDest2;
I use the mongoDB C# driver 2.1.1 to store and retrieve documents in a mongoDb collection. This worked well so far until one document was CORRECTLY stored but could not be read back by the driver.
I got to that conclusion using robomongo (a user interface to monitor what's inside my collection) and manipulating the object stored.
It contains a collection of elements (around 4000 sub elements) and if I remove enough of it, the document is finally retrievable again.
The line of code used is:
public Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken))
{
return MongoQueryable.FirstOrDefaultAsync(_collection, predicate, cancellationToken);
}
Before you ask, what I first thought is that one specific element of my sub elements set had encountered some issues while being serialized/deserialized and was creating the issue. I tested by removing randomly elements of the collection, and just the number seems to be the root of the problem.
The text file size of the Json document represents around 11 Mb - I will try now to get the actual size of the object which would be more relevant.
Something else I can add is that in the mondoDb log file, there is one line that only appear when I try to select an "oversized" document :
2016-06-29T19:30:45.982+0200 I COMMAND [conn12] command MYCOLLECTIONDb.$cmd command: aggregate
{ aggregate: "XXXX", pipeline: [ { $match: { _id: "5773e0e9a1152d259c7d2e50" } }, { $limit: 1 } ]
, cursor: {} } keyUpdates:0 writeConflicts:0 numYields:0 reslen:4188200 locks:{ Global:
{ acquireCount: { r: 6 } }, MMAPV1Journal: { acquireCount:
{ r: 3 } }, Database: { acquireCount: { r: 3 } }, Collection: { acquireCount: { R: 3 } } } 109ms
(XXXX being my custom object)
So I'd like to know if you have any idea of what's causing this issue, any hint of where I should try to look, because I am running out of ideas :)
EDIT_1: That is basically the structure of my object :
[DataContract]
public class MyClass
{
[DataMember]
public string _id { get; set; }
[DataMember]
public string XmlPreference { get; set; }
[DataMember]
public string XmlMarketDates { get; set; }
[DataMember]
public IEnumerable<ClassB> Lines { get; set; }
}
[DataContract]
public class ClassB
{
[DataMember]
public string UniqueId { get; set; }
[DataMember]
public string ParentId { get; set; }
[DataMember]
public Dictionary<string, ClassC> DataMapping {get; set;}
}
and ClassC is just a container of 7 ints and 1 object properties.
Still looking for something :)
EDIT 2: I reproduced the bug only using the mongoDb C# drivers 2.1.1 release version. Here is the code :
using MongoDB.Bson;
using MongoDB.Driver.Linq;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace TestingMongoDbCsharpDriver
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Debugging starting...");
try
{
MongoDB.Driver.MongoClient myClient = new MongoDB.Driver.MongoClient("mongodb://localhost:27010");
var db = myClient.GetDatabase("DocumentStoreDb");
var collection = db.GetCollection<DocumentModel>("TestOverload");
Console.WriteLine("Collection TestOverload found");
Random rand = new Random(999999999);
DocumentModel toInsert = null;
for (int lineNb = 1; lineNb < 50000; lineNb += 1000)
{
string id = rand.Next().ToString();
Console.WriteLine(string.Format("\nCreating document with id '{0}' and {1} lines...", id, lineNb));
toInsert = Funcs.Create(id, lineNb);
Console.WriteLine("Created.");
// Saving and waiting for it to finish
collection.InsertOneAsync(toInsert).Wait();
Console.WriteLine("Inserted.");
// retrieving it
var filter = new BsonDocument("_id", new BsonDocument("$eq", id));
var cursor = collection.FindAsync<DocumentModel>(filter).Result;
cursor.MoveNextAsync().Wait();
string messFilterMethod = cursor.Current.Count() == 1 ? "Retrieved" : "Not retrieved. Bug confirmed";
Console.WriteLine("With Filter: " + messFilterMethod);
var model = MongoQueryable.FirstOrDefaultAsync(collection.AsQueryable(), e => e._id == id).Result;
string mess = model != null ? "Retrieved" : "Not retrieved. Bug confirmed";
Console.WriteLine("With AsQueryable: " + mess);
// Removing it
collection.DeleteOneAsync(filter).Wait();
Console.WriteLine("Deleted.\n");
Console.ReadKey();
}
}
catch (Exception e)
{
Console.WriteLine("\n\nERROR: " + e.Message);
}
Console.WriteLine("\n\n**************** NO BUG *************\n");
}
}
public static class Funcs
{
public static DocumentModel Create(string uniqueId, int nbLines)
{
Random random = new Random(2000000);
List<MyDocumentSubElement> listOk = new List<MyDocumentSubElement>();
for (int lines = 0; lines < nbLines; ++lines)
{
Dictionary<string, SnapCellValueStyle> newDico = new Dictionary<string, SnapCellValueStyle>();
for (int i = 0; i < 10; ++i)
{
int idSnap = random.Next();
var snap = new SnapCellValueStyle()
{
alignment = idSnap,
Value = "okkkkkkkkkkzzzzkk"
};
newDico.Add("newKey_" + idSnap.ToString(), snap);
}
MyDocumentSubElement doc = new MyDocumentSubElement()
{
Icon = 516,
Name = "name du truc",
ParentId = "parent id",
type = SubElementType.T3,
UniqueId = "uniqueId_" + random.Next().ToString(),
MapColumnNameToCellValue = newDico
};
listOk.Add(doc);
}
int headerId = random.Next();
MyDocumentHeader temp = new MyDocumentHeader()
{
Comment = "comment",
Date = DateTime.Now,
ExtractionId = headerId,
Id = "id ok _ " + headerId,
Name = "Name really interesting name",
OwnerId = 95115,
RootFolioId = 51,
SnapshotViewId = MyDocumentType.Type2
};
DocumentModel toInsert = new DocumentModel()
{
_id = uniqueId,
Header = temp,
XmlMarketDates = "<xmlPrefok65464f6szf65ze4f6d2f1ergers5fvefref3e4f05e4f064z68f4xd35f8eszf40s6e40f68z4f0e8511xf340ed53f1d51zf68d4z61ef644dcdce4f64zef84zOKok>><>>",
XmlPreference = "<<zefaiunzhduiaopklzpdpakzdplapdergergfdgergekâzda4684z16ad84s2dd0486za04d68a04z8d0s1d d4az80d46az4d651s1d8 154efze40f6 4ze65f40 65ze40f6z4e>><>>>",
Lines = listOk
};
return toInsert;
}
}
// Imitation of SnapshotDocModel
[DataContract]
public class DocumentModel
{
[DataMember]
public string _id { get; set; }
[DataMember]
public MyDocumentHeader Header { get; set; }
[DataMember]
public string XmlPreference { get; set; }
[DataMember]
public string XmlMarketDates { get; set; }
[DataMember]
public IEnumerable<MyDocumentSubElement> Lines { get; set; }
}
[DataContract]
public class MyDocumentHeader
{
[DataMember]
public string Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public int OwnerId { get; set; }
[DataMember]
public string Comment { get; set; }
[DataMember]
public DateTime Date { get; set; }
[DataMember]
public int RootFolioId { get; set; }
[DataMember]
public MyDocumentType SnapshotViewId { get; set; }
[DataMember]
public int ExtractionId { get; set; }
}
[DataContract]
public class MyDocumentSubElement
{
[DataMember]
public string UniqueId { get; set; }
[DataMember]
public string ParentId { get; set; }
[DataMember]
public int Icon { get; set; }
[DataMember]
public SubElementType type { get; set; }
[DataMember]
public Dictionary<string, SnapCellValueStyle> MapColumnNameToCellValue { get; set; }
[DataMember]
public string Name { get; set; }
}
public class SnapCellValueStyle
{
public object Value { get; set; }
public int alignment { get; set; }
public int Red { get; set; }
public int Green { get; set; }
public int Blue { get; set; }
public int currency { get; set; }
public int decimalPoint { get; set; }
public int kind { get; set; }
public int style { get; set; }
}
#region enum
public enum MyDocumentType
{
Undefined,
Type1,
Type2,
Type3,
Type4,
Type5
}
public enum SubElementType
{
T1,
T2,
T3
}
#endregion
}
If you test it, you will see that there is the point where the AsQueryable method does not work anymore where as the document is still retrievable by the method using a filter.
Problem fixed in the version 2.2.4 of the c# mongo db driver (probably with the bug https://jira.mongodb.org/browse/CSHARP-1645)
Thanks :)
I wonder if there's any way to match the names in a list with the elements in a class:
I have a class:
public class exampleClass
{
public string name { get; set; }
public string value { get; set; }
}
and a List: List<exampleClass> EnfSist
So that's the way the list is made. Now I would like to know how to match or identify the string inside "name" from my list. To match this class:
tbl_sistematicas b = new tbl_sistematicas
{
ap_enf_id_enfermedad = Convert.ToInt32(EnfSist[0].value),
ap_pac_inicio = Convert.ToInt32(EnfSist[1].value),
ap_pac_inicio_periodo = Convert.ToInt32(2].value),
ap_pac_duracion = Convert.ToInt32(EnfSist[3].value),
ap_pac_duracion_periodo = Convert.ToInt32(EnfSist[4].value),
ap_pac_tratamiento = EnfSist[5].value
};
Once being able to match the same names I won't have to specify each index of every element in the list. The elements in the list have the same name as in the table. Not all elements of the class are being used.
I have something like this: tbl_sistematicas bh = EnfSist.FindAll(x => x.name == bh.?????? );
If I understand the question, you can do this using something like automapper or ValueInjector
An example using ValueInjector
void Main()
{
List<exampleClass> EnfSist = new List<exampleClass>();
EnfSist.Add(new exampleClass { name = "ap_enf_id_enfermedad", value = "12" });
EnfSist.Add(new exampleClass { name = "apap_pac_inicio" , value = "34" });
// etc
tbl_sistematicas b = new tbl_sistematicas();
b.InjectFrom<MyInjection>(EnfSist);
}
public class MyInjection : KnownSourceValueInjection<List<exampleClass>>
{
protected override void Inject(List<exampleClass> source, object target)
{
foreach(var entry in source)
{
var property = target.GetProps().GetByName(entry.name, true);
if (property != null)
property.SetValue(target, Convert.ChangeType(entry.value, property.PropertyType));
}
}
}
public class exampleClass
{
public string name { get; set; }
public string value { get; set; }
}
public class tbl_sistematicas
{
public int ap_enf_id_enfermedad { get; set; }
public int apap_pac_inicio { get; set; }
public int ap_pac_inicio_periodo { get; set; }
public int ap_pac_duracion { get; set; }
public int ap_pac_duracion_periodo { get; set; }
public string ap_pac_tratamiento { get; set; }
}
Note, this will throw an exception if the value can not be converted to an int