I have a variable [User::WorkOrderProductIdList] in SSIS package containing records of a class object.
Work Order Product class
public class WorkOrderProduct
{
public Guid workOrderId;
public Guid workOrderProductId;
public static Guid WorkOrderId { get; set; }
public static Guid WorkOrderProductId { get; set; }
}
Main Script Task
public override void InputWOProduct_ProcessInputRow(InputWOProductBuffer Row)
{
ArrayList wopList = new ArrayList();
WorkOrderProduct wop = new WorkOrderProduct();
wop.workOrderId = pWorkOrderID;
wop.workOrderProductId = pWorkOrderProductID;
wopList.Add(wop);
}
Assign wopList to [User::WorkOrderProductIdList]
public override void PostExecute()
{
base.PostExecute();
Variables.WorkOrderProductIdList = this.wopList;
}
In another script task, it takes in [User::WorkOrderProductIdList] as ReadOnlyVariables.
May I know how can I loop through [User::WorkOrderProductIdList] and extract the values of workOrderId and workOrderProductId for each row?
I saw that my ArrayList [User::WorkOrderProductIdList] contains the records and values, but there are no functions when . on the field.
Population
Intellisense issue aside, you'll only ever have at most 1 row in there
You are using a Data Flow and within that, you have a Script Component acting as a Transformation.
In InputWOProduct_ProcessInputRow which fires for each row that passes through the component, you have
Every time a new row comes in, you are going to empty out the existing ArrayList and reinitialize it.
Instead, you need to have that variable at the class scope and have the initialization logic in the not-shown PreExecute method
ArrayList wopList;
// Or, if you wish to use the Generics
// List<WorkOrderProduct> wopList
public override void PreExecute()
{
base.PreExecute();
/*
* Add your code here
*/
this.wopList = new ArrayList();
// Or
// this.wopList = new List<WorkOrderProduct>();
}
Consumption
You use the ArrayList to hold the elements of your array but that is a weakly typed list.
We don't recommend that you use the ArrayList class for new development. Instead, we recommend that you use the generic List class.
When you're enumerating through it in your foreach loop, what is getting popped off the list is of type Object. Not only do I just "know" that, itellisense is telling you that all it knows is the type is Object because it's giving you the functions that everything has because they're all derived from Object.
Yes, the Watch window has inspection magic to show you what the values are but do you think the team that wrote the former is the same team that wrote the latter?
Since you "know" what the type should be, declare it as such.
foreach (WorkOrderProduct wopObj in ...
However, the next logical error, probably, is going to be in the accessing of
Variables.WorkOrderProductIdList itself. Your snipped image there shows you're shredding out the array in the PreExecute method. The sequence of operations is that the Data Flow is going to go through validation, then pre-execute sequences so at that point, it's going to shred the results of your array list and the value of wopObj_workOrderId is going to be the last element of your array.
Related
Assuming I will need to access the values contained within a given file a small number of times, from different methods, can I include some sort of boolean value within a method to determine whether or not it is appropriate to call the file?
Lets say I have the file config.cfg. In that file, there are three values:
string/name>max|
bool/adult>yes|
int/age>20|
The method getUserName() returns the value of "max". It does this by calling the file:
using (StreamReader reader = new StreamReader(path))
{
//get line beginning with string/name here
return //string value containing name
}
Let's assume I need to use the value of name several times, as well as the values isAdult and clientAge. Rather than accessing the file over and over again, it could be much easier to save the requested value in some form of static variable. However, this variable still needs to be changed in value at least once, when the method is first called.
Can I do this inside the method getUserName()?
Furthermore, is this idea even possible within the bounds of OOP? Is it a similar concept to Prefetch?
It really looks to me that you need to access a field in a lazy way (i.e. only if needed, when needed). If so .NET has Lazy class for such cases which also provides thread safety out of the box:
public static Lazy<string> Name { get; } = new Lazy<string>(() => ReadNameFromFile());
Lazy will also ensure that you only create value once (i.e. call initiailization method) and on later calls it will simply return already retrieved value.
Create a static class. Something like this:
public static class ClientConfig{
public static string Name{get;set;}
public static bool IsAdult{get;set;}
public static int Age{get;set;}
public static void Load(){
// load your values
// ClientConfig.Name = name from file etc.
}
public static void Save(string newName, int age, bool value){
// save your values to the config file
}
}
And call ClientConfig.Load() first time when your app starts, for example (or whenever you need to retrieve config data)
My question is: Can I define a static method "meth1" in a static class "classB" that, when called from "classA", searches for a specific field (in "classA", not in the class in which is defined)?
I try to explain better: I need to do something like this:
public class classA
{
string someText;
int anInt;
bool trueOrFalse;
public classA()
{
...
...
var variable = classB.meth1("variableName");
...
...
}
}
public static classB
{
public static object meth1(string name)
{
...
... //use "name" to find the variable with that name in the class from which "meth1" is called.
...
}
}
That because I have to read a backup of "last run values" of variables contained in a .txt file, written line by line as "variable name = value".
So I read the .txt, create an hashtable "backupHashtable" which contains ("variable name";"value"), and then I want to search variables by string "variable name" and reset them to "value".
If someone of you knows a better procedure I'm listening. Maybe the use of a Dictionary?
Thank you!
UPDATING
Ok, now I have a clearer idea of what I want to do: I want to implement a class "ClassB", separate from my main class "classA". In this new class I would have a "meth1" method which, running in a separate thread, saves every 10 seconds (for example) the state of some variables belonging to "classA". To communicate the "meth1" what are the variables that he has to save, I want to use a list containing the names (in the format "string", that's what I thought, but I guess it's not the only way) of these variables.
If you're wondering why I want to do this in a separate thread the answer is this: my application performs some recognition operation of some objects in live stream images from multiple cameras and then ancillary operations must be isolated as much as possible from the main code to increase the speed of execution.
Now, perhaps, it is more understandable what I said before.
Yes, but you also need to pass a reference to the instance of A. Then use reflection to get or set the property.
public static void Meth1(object obj, string propertyName)
{
var prop = obj.GetType().GetProperty(propertyName);
var value = prop.GetValue(obj);
...
}
If I were to get values from a textfile into a class, I think I'd load them in a dictionary first, and then set all properties one by one. (Maybe unless there are, say, hundreds of properties). When using reflection, there is a chance that the textfile contains the name of a property you don't want to be changed from outside.
object value;
if (dict.TryGetValue("someProperty", out value)) { a.SomeProperty = value; }
As strange as it might sound, I want to access something that is not.
Here's an example:
int tempVar = myObject.myVar // myVar does not exist;
In reality I want the class to run a method, that would take the non-existing variable as a parameter:
object returningVariables(string variableName)
{
object desiredObject; // a concrete object that I have stored somewhere in an array inside the class
// going trough some List that contains names of all variables, when it finds it
// return it
return desiredObject;
}
I'll try to explain in a concrete example what I want to achieve and why.
I have a class that stores stats of an object: name, level, speed, size, etc.
They are supposed to be accessed trough a method StatData getStat(string statName);
Stats are created trough a method void MakeStat(). The problem began when some stats were created in the class as public variables and accessed by other classed not trough the getStat() method.
Now that the public variables are changed, deleted or new ones added it takes some refactoring to get the app working again. And it looks bad when there are mixed calls with direct access to a public variable and a method for the same thing.
Please note, I do know how to fix my code the standard way; I am merely interested if above described technique will work.
Sounds like DynamicObject would help you here. You can override different methods for of that class for whatever is being called/accessed on that object: members, invocations, etc. Using dynamic means you won't be able to use intellisense anymore however. You can find more info here.
public class MyDynamicObject : DynamicObject {
public override bool TryGetMember(GetMemberBinder binder, out Object result){
if (binder.Name == "myVar"){
result = "xyz";
return true;
}
result = null;
return false;
}
}
// Usage
dynamic x = new MyDynamicObject();
Console.WriteLine (x.myVar); // will output "xyz"
so ive been doing this assignment all night now and I think ive gone completely wrong on one part. this is the section im stuck on:
TableOrder class will carry two methods for adding items from the menu:
AddFood(), AddDrink(). Each method will pass in a prepared instance of
either the FoodItem or DrinkItem class you previously created. It is expected that the order system will maintain a separate collection
of drinks from food given that we will be passing the drinks orders to
bar staff and likewise food orders to the kitchen.
I have previously created two classes to for FoodItem and DrinkItem but am struggling to grasp the concept of what the question is asking. Please help!
hopefully somebody can explain what it is i am doin wrong. this is the code i have so far...
List<DrinkItem> DrinkMenu = new List<DrinkItem>();
public DrinkItem AddDrink(DrinkItem drinkItem)
{
return drinkItem;
}
public List<DrinkItem> OrderedDrink
{
get
{
return DrinkMenu;
}
}
the next section is as follows:
The TableOrder class provides two separate properties given below, each of which returns a copy of the stored items. Each are expected to return an instance of the List class where T is the appropriate class. It is not expected that I can set these food and drink using these properties.
a. OrderedFood
b. OrderedDrink.
i have ammended the first section and it works, but it has now given me errors on my 2nd part... any ideas as to why this might have happened?
I am going to try to give you some ideas.
First of all you need to have a TableOrder class
public class TableOrder
{
}
Responsibility of the class is: class will carry two methods for adding items from the menu
So, you create two methods in the class who will add things to the order list:
public void AddFood()
{
}
public void AddDrink()
{
}
You also need order list and according to the requirement you need two order lists one for food and another for drink. So, you put two fields in the class like,
private List<FoodItem> FoodOrders = new List<FoodItem>();
private List<DrinkItem> DrinkOrders = new List<DrinkItem>();
In the method you just pass items and add them to this list
public void AddFood(FoodItem fo)
{
FoodOrders.Add(fo);
}
public void AddDrink(DrinkItem do)
{
DrinkOrders.Add(do);
}
And while you are using TableOrder you just need to call these methods to add orders like,
tableOrder.AddDrink(drinkItem);
As i understand this the AddDrink Method should add the Drink to the OrderedDrink List eachtime a Drink is ordered:
public DrinkItem AddDrink(DrinkItem drinkItem)
{
OrderedDrink.Add(drinkItem);
return drinkItem;
}
And if the return value is not needed you may consider declaring the Method as void.
Important would also be to empty the OrderedDrink List eachtime its passed to the kitchen.
The question is asking you to write a class TableOrder which contains two collections. One for storing the ordered DrinkItemss and one for storing the ordered FoodItems. This class should provide two methods:
AddDrink which gets passed a DrinkItem and adds it to the other drinks stored in your collection
AddFood which gets passed a FoodItem and adds it to the collection of ordered foods
In general a method which only returns its parameter without doing anything else like you have written for AddDrink is completely useless so this is an quick and easy check if what you wrote can be right.
Good Day,
I have a situation where I'm using code that contains a class called ImportFileContext. The code looks like:
// One of 5 different types can be passed in
public AddImportData(CustomType ModelData)
{
// Depending on which 5 different types, the formatted type will change
FormattedType data = ConvertModelDataToFormattedData(ModelData);
using (var db = new ImportFileContext())
{
// Can this next line be made dynamic?
db.ImportFormattedData.Add(data);
db.SaveChanges();
}
}
Basically, a CustomType will always be passed in to the method. However, there are five different custom types that can be passed in. Depending on which 5 can be passed in, the data will be modified.
Use cases:
Custom Type passed in, format data to a specific format, then add that item to
List of the db instance.
Custom Type 2 passed in, format data to a specific format, then add that item to
List of the db instance.
Custom Type 3 passed in, format data to a specific format, then add that item to
List of the db instance.
So what I'm looking for is a way add an item to the List depending on the data type without having to write several different methods to test which type I'm receiving then adding the item. I know of the strategy pattern and I could use that, but what about adding an item to a list?
I'm really trying to avoid writing code that would look like:
// One of 5 different types can be passed in
public AddImportData(CustomType ModelData)
{
// Depending on which 5 different types, the formatted type will change
FormattedType data = ConvertModelDataToFormattedData(ModelData);
using (var db = new ImportFileContext())
{
if (typeof(ModelData) == "CustomType")
db.ImportFormattedData.Add(data);
elseif (typeof(ModelData) == "CustomType1")
db.ImportCsvData.Add(data);
elseif (typeof(ModelData) == "CustomType2")
db.ImportTabDelimetedData.Add(data);
db.SaveChanges();
}
}
TIA,
coson
I don't know how feasible this is for your application, but you can always add the specific behavior to the CustomType class and subclasses can implement it however they need to.
public class CustomType
{
public virtual void FormatAndWriteToDB(DataBase db);
}
And then sublasses override as needed
public class CustomType1 : CustomType
{
public override void FormatAndWriteToDB(DataBase db)
{
FormattedType data = ConvertModelDataToFormattedData(ModelData);
db.ImportCsvData.Add(data);
}
}
That would make your code very clean in the example method:
public AddImportData(CustomType ModelData)
{
ModelData.FormatAndWriteToDB(db);
db.SaveChanges();
}
Of course you can change this around a bit. For example, if the FormattedType call is common to all of them, you could leave that in the AddImportData method and pass it as an argument to the FormatAndWriteToDB method.
The advantage of this is future additions just require implementing the new subclass of CustomType and no modification is needed to AddImportData.
Sounds to me like you're looking for double-dispatch. You can do this with the Visitor Pattern--which is basically what David Mason detailed--where you decouple the algorithm from the data by putting logic (the visit) into the class that contains the data. That, of course works, but requires you to modify the class outside of the algorithm in order to visit.
I find this complex and it's really just there because statically typed object oriented languages don't normally do runtime overloading. Fortunately in C# 4 they introduced the dynamic keyword which allows use to implement double dispatch much easier--or at least in a way that looks more like method overloading. Which means you create the method overloads, assign the value to dynamic variable, then invoke the method. The method that gets call will be chosen at runtime based on the value. For example:
public static void AddImportData(CustomType ModelData)
{
FormattedType data = ConvertModelDataToFormattedData(ModelData);
using (var db = new ImportFileContext())
{
dynamic temp = ModelData;
ImportData(ModelData, data, db);
}
}
private static void ImportData(CustomType modelData, FormattedType data, ImportFileContext db)
{
db.ImportFormattedData.Add(data);
db.SaveChanges();
}
private static void ImportData(CustomType1 modelData, FormattedType data, ImportFileContext db)
{
db.ImportCsvData.Add(data);
db.SaveChanges();
}
private static void ImportData(CustomType1 modelData, FormattedType data, ImportFileContext db)
{
db.ImportTabDelimetedData.Add(data);
db.SaveChanges();
}
I have more details on my blog at: http://msmvps.com/blogs/peterritchie/archive/2010/05/24/using-the-dynamic-keyword-in-c-to-improve-object-orientation.aspx