Issues with appending array to anonymous array - C# - c#

I'm trying to append array to anonymous array and I received this error:
No best type found for implicitly typed-array.
Here is the array I want to append:
var products = myProductList.Select(x => new
{
isAvailable = 0,
photo = x?.ImageUrl
}).ToArray();
Here is the part of the code where I'm trying to append it (my products array) to, so I want to append rest of the array data to productImages anonymous array:
var articles_data = new
{
products = new[]
{
new
{
prodDate = product.GetDate();
prodtOrdNumb = product.OrdinalNumber,
productAmount = product.Amount
}),
productImages = new[] {
new
{
isAvailable = 1,
photo = productFile?.ImageUrl
},
products.ToArray() // HERE I TRIED TO APPEND MY ARRAY
}
}
}
};
As you can see guys I have posted where I've tried to append my array and I've received:
No best type found for implicitly typed-array.
Any kind of help would be awesome!
Thanks!

Related

Add and populate an IEnumerable property to an API call

I'm using an older 3rd party API to connect to a legacy system.
Here is the code:
AutoMaximizer.AuthUser yourCredentials = new AutoMaximizer.AuthUser
{
UserKey = "x1213"
};
AutoMaximizer.Pagers availableCars = new AutoMaximizer.Pagers
{
TotalCalls = 65,
Router = 91220
};
ISessionManagement s = new ManagementClient();
FactoryResponse response;
response = await s.GetAll(yourCredentials, new ListRequest
{
Pagers = availableCars,
SortIncreasing = true
});
It's working, but I want to add another property when I make the request.
The property is called Types and is a IEnumerable<Type>. The API docs state:
Types = Gets or sets an enumeration of types to include in the response.
And in the API reference, I found it:
public enum Type : int
{
[System.Runtime.Serialization.EnumMemberAttribute()]
Auto = 0,
[System.Runtime.Serialization.EnumMemberAttribute()]
Truck = 1,
[System.Runtime.Serialization.EnumMemberAttribute()]
Motorcycle = 2
}
But I'm not quite sure how to add it to the GetAll method.
I tried adding this:
List<AutoMaximizer.Type> types = new List<AutoMaximizer.Type>();
types.Add(AutoMaximizer.Type.Auto);
types.Add(AutoMaximizer.Type.Truck);
types.Add(AutoMaximizer.Type.Motorcycle);
And then this:
response = await s.GetAll(yourCredentials, new ListRequest
{
Pagers = availableCars,
SortIncreasing = true,
Types = types
});
But that gives me this error:
Cannot implicitly convert type Systems.Collections.Generic.List<AutoMaximizer.Type> to AutoMaximizer.Type[]
I am not sure what to do now...
Is there a way to get this to work?
Thanks!
Read your error, it wants an array, not a list:
response = await s.GetAll(yourCredentials, new ListRequest
{
Pagers = availableCars,
SortIncreasing = true,
Types = new[] { Type.Auto, Type.Truck, Type.Motorcycle },
});
According to the error, the ListRequest is specifically looking for an array, not any generic collection. You can convert the list to an array:
response = await s.GetAll(yourCredentials, new ListRequest
{
Pagers = availableCars,
SortIncreasing = true,
Types = types.ToArray()
});
Or just use an array to begin with:
AutoMaximizer.Type[] types = new [] { AutoMaximizer.Type.Auto, AutoMaximizer.Type.Truck, AutoMaximizer.Type.Motorcycle };

Cannot implicitly convert type 'F_M.Commitment_Ledger_Data__Public_Type' to 'F_M.Commitment_Ledger_Data__Public_Type[]'

I am trying to use the "Put_Ledger" function inside the Financial_management API in Workday, but I keep on getting an error when I try to add the object[] to the object (as it states in the API to do).
Workday has been no help in solving this issue. Here is a sample of the code. The objects are creates, and then added to parent objects:
Ledger_Only_DataType ldOnly = new Ledger_Only_DataType
{
Actuals_Ledger_ID = "1234567",
Can_View_Budget_Date = true
};
//Commitment_Ledger_data
Commitment_Ledger_Data__Public_Type cl = new Commitment_Ledger_Data__Public_Type
{
Commitment_Ledger_Reference = ledgerObject,
Enable_Commitment_Ledger = true,
Spend_Transaction_Data = st,
Payroll_Transaction_Data = pt
};
// This is where the error occurs:
ldOnly.Commitment_Ledger_Data = cl;
Error message:
"Cannot implicitly convert type 'CallWorkdayAPI.Financial_Management.Commitment_Ledger_Data__Public_Type' to 'CallWorkdayAPI.Financial_Management.Commitment_Ledger_Data__Public_Type[]"
Use lists and convert them to an array. It's easier:
List<Commitment_Ledger_Data__Public_Type> cls = new List<Commitment_Ledger_Data__Public_Type>();
Commitment_Ledger_Data__Public_Type cl1 = new
Commitment_Ledger_Data__Public_Type
{
Commitment_Ledger_Reference = ledgerObject,
Enable_Commitment_Ledger = true,
Spend_Transaction_Data = st,
Payroll_Transaction_Data = pt
};
cls.Add(cl1);
ldOnly.Commitment_Ledger_Data = cls.ToArray();
You can simplify and do it inside the initializer as well
Not familiar with Workday, but I am assuming
ldOnly.Commitment_Ledger_Data
Is an array of: Commitment_Ledger_Data__Public_Type
So you need to set it equal to an array of that type, whereas currently you are setting it equal to a single object of that type.
Ledger_Only_DataType ldOnly = new Ledger_Only_DataType
{
Actuals_Ledger_ID = "1234567",
Can_View_Budget_Date = true
};
//Commitment_Ledger_data
Commitment_Ledger_Data__Public_Type cl = new
Commitment_Ledger_Data__Public_Type
{
Commitment_Ledger_Reference = ledgerObject,
Enable_Commitment_Ledger = true,
Spend_Transaction_Data = st,
Payroll_Transaction_Data = pt
};
Commitment_Ledger_Data__Public_Type[] cls = new Commitment_Ledger_Data__Public_Type[1];
cls[0] = cl;
ldOnly.Commitment_Ledger_Data = cls;
The error message is telling you what the problem is - you're trying to assign a single instance of a Commitment_Ledger_Data__Public_Type type to an object that represents an array of that type (Commitment_Ledger_Data).
You should be able to do the assignment using an array (with the single item you created as it's only member) instead:
ldlOnly.Commitment_Ledger_Data = new[] {cl};
Or you could shorten the whole thing to use initializer syntax:
var ldOnly = new Ledger_Only_DataType
{
Actuals_Ledger_ID = "1234567",
Can_View_Budget_Date = true,
Commitment_Ledger_Data = new[]
{
new Commitment_Ledger_Data__Public_Type
{
Commitment_Ledger_Reference = ledgerObject,
Enable_Commitment_Ledger = true,
Spend_Transaction_Data = st,
Payroll_Transaction_Data = pt
}
}
};

Invalid expression term 'foreach'

I'm trying to initalize an object for serialization, the class object was created using xsd.exe. The individual properties can be initialised without issue but when trying to initialise an 'unbounded' XSD property i can't use a foreach loop to go over each value in an array and add that to the object:
object[] test = new object[0];
test[0] = "ring";
export export = new export();
export.info = new exportInfo
{
dateandtimeofexport = DateTime.Now,
duration = "10",
planningsoftware = new exportInfoPlanningsoftware
{
name = "",
major = "",
minor = "",
revision = "",
build = ""
},
exporter = new exportInfoExporter
{
version = new exportInfoExporterVersion
{
name = "",
major = "",
minor = "",
revision = "",
build = ""
},
module = new exportInfoExporterModule[]
{
foreach(Object x in test)
{
new exportInfoExporterModule{name = x.name, major = x.major, minor = x.minor, revision = x.revision, build = x.build;}
}
}
}
};
I think the main problem here is my understanding of exactly how to initialise an array of objects under the object class created from my XSD using XSD.exe, can anyone advise on how this might be done without the foreach loop?
Any guidance is much appreciated.
Your code is not valid c#. You cannot use foreach inside an array initializer.
// NOT VALID C# CODE!
module = new exportInfoExporterModule[]
{
foreach(Object x in test)
{
new exportInfoExporterModule{name = x}
}
}
This is not possible, because foreach is a statement, but the array intializer expects an expression that results in a exportInfoExportedModule.
What you can do instead is something like this:
module = test.Select(x => new exportInfoExporterModule{name = x}).ToArray()
But note that at the start of your code you create the array test with length 0 and then try to set "ring" as its first (of zero) elements! That gives an IndexOutOfRangeException. Initialize test like that:
object[] test = new object[] {"ring"};
module = test.Select(t => new exportInfoExporterModule{name = t}).ToArray()
instead of
module = new exportInfoExporterModule[]
{
foreach(Object x in test)
{
new exportInfoExporterModule{name = x}
}
}
should do the trick. Learn some LINQ at it will get clear what happened here ;)
You can't use a loop within an initializer.
See if you can initialize the array after you've constructed the rest of the object:
export.info = new exportInfo
{
// ...
version = new exportInfoExporterVersion
{
name = "",
major = "",
minor = "",
revision = "",
build = ""
}
}
};
export.info.exporter.module = new exportInfoExporterModule[test.Length];
for (int i = 0; i < test.Length; i++)
{
export.info.exporter.module[i] = new exportInfoExporterModule
{
name = test[i].name,
major = test[i].major,
minor = test[i].minor,
build = test[i].build,
revision = test[i].revision
};
}
Or, with LINQ:
export.info = new exportInfo
{
// ...
version = new exportInfoExporterVersion
{
name = "",
major = "",
minor = "",
revision = "",
build = ""
},
module = test.Select(x => new exportInfoExporterModule
{
name = x.name,
major = x.major,
minor = x.minor,
build = x.build,
revision = x.revision
}).ToArray()
}
};
The first two lines of your code will result in a runtime exception, as you're attempting to put a value in a zero-length array.
object[] test = new object[0];
test[0] = "ring";
Run-time exception (line -1): Index was outside the bounds of the array.
Here is a .NET Fiddle to show that.
Iterating over an array via a foreach is totally fine! But the issue is really that the loop is within an object initializer. This is not permitted, instead use Linq with a .Select and .ToArray().
module = test.Select(t => new exportInfoExporterModule { name = t })
.ToArray();
You have to create the array you want to assign before you create your exporter object.
Another way could be to use Linq to assign module. Something like
module = test.Select(x => new exportInfoExporterModule{name = x}).ToArray()
should work.
To be able to use a foreach you have to iterate on a container implementing interface IEnumerable.
It is not the case of a simple array. Just transform test in a List (List implements IEnumerable) and it should work.
List<object> test = new List<object>();

C# elegant way to assign properties values rather then duplication

i have searched for something similiar in stackoverflow and couldnt find anything which will give me some hint.
i have following code:
DATA val1 = new DATA();
val1.Name = "KeyValue";
val1.Value = "805373069";
DATA val2 = new DATA();
val2.Name = "Tel";
val2.Value = "0123456789";
DATA val3 = new DATA();
val3.Name = "TargetID";
val3.Value = "43301";
DATA val4 = new DATA();
val4.Name = "ServiceLevel";
val4.Value = "Y";
DATA val5 = new DATA();
val5.Name = "TypeId";
val5.Value = "13505";
DATA val6 = new DATA();
val6.Name = "DateTime";
val6.Value = System.DateTime.Now.ToString("ddMMyyyyHHmmssffftt");
DATA val7 = new DATA();
val7.Name = "DbDateTime";
val7.Value = System.DateTime.Now.ToString("ddMMyyyyHHmmssffftt");
and once all the objects are populated i put them in Single array.
i.e. to be used somewhere else
DATA[] array = {val1,val2,val3,val4,val5,val6,val7};
and Proxy class which i cant change is:
public partial class DATA {
private string nameField;
private string valueField;
public string Name {
get {
return this.nameField;
}
set {
this.nameField = value;
this.RaisePropertyChanged("Name");
}
}
public string Value {
get {
return this.valueField;
}
set {
this.valueField = value;
this.RaisePropertyChanged("Value");
}
}
Now what i have tried and failed to make it easier is used Dictionary and also jagged array and multi dimensional array which didnt worked as i hoped.
can someone give me hint of a better solution then having 7 different objects created, as this data is dynamic i have to do this runtime data population.
suggestions please?
You could just declare the objects in-line as part of the array declaration, if all you're trying to do is avoid having the variables:
DATA[] array = {
new DATA { Name = "something", Value = "something else" },
new DATA { Name = "something", Value = "something else" },
new DATA { Name = "something", Value = "something else" },
new DATA { Name = "something", Value = "something else" }
};
Anywhere that you have a variable, you can instead have the operation which created that variable. The order of operations will result in evaluating to the same thing. Where you'd need a variable is where you want to use the same instance of something multiple times, or the same value without having to re-calculate it.
Put all data in a dictionary if you want to make sure names must not be duplicated:
var data = new Dictionary<string, string>();
// fill dictionary:
data.Add("name1", /*value*/);
data.Add("name2", /*value*/);
data.Add("name3", /*value*/);
data.Add("name4", /*value*/);
Then convert it to array:
return data.Select(d => new Data(){ Name = d.Key, Value = d.Value}).ToArray();
Make sure you have included using System.Linq in top.
UPDATE:
As #LukeH suggested, You can simply use collection initializer like this:
var data = new Data[]
{
new Data(){ Name = "Sylvester", Value = /*value*/ },
new Data(){ Name = "Whiskers", Value = /*value*/ },
new Data(){ Name = "Sasha", Value = /*value*/ }
};
Which doesn't prevent duplicate names for Data type instances.
You can create extension method something like this to overcome the problem of assign properties values rather then duplication,
static class Extensions
{
public static void AddDataObject(this List<DATA> dataList, params string[] values)
{
dataList.Add(new DATA() { Name = values[0], Value = values[1] });
}
}
and passing that values as per given below,
List<DATA> dataList = new List<DATA>();
dataList.AddDataObject("KeyValue", "805373069");
dataList.AddDataObject("Tel", "0123456789");
Here in above example I used List instead of array, you can change according to your requirements
You could initialize an anonymous object and then convert to an array of data like this:
var data = new {
KeyValue="805373069",
Tel="0123456789",
TargetID="43301",
ServiceLevel="Y",
TypeId="13505",
DateTime=System.DateTime.Now.ToString("ddMMyyyyHHmmssffftt"),
DbDateTime=System.DateTime.Now.ToString("ddMMyyyyHHmmssffftt")
};
var array = data.GetType()
.GetProperties()
.Select(x=>new DATA{Name=x.Name,Value=(string)x.GetValue(data)})
.ToArray();
You could also do it like this:
var data = new {
KeyValue="805373069",
Tel="0123456789",
TargetID="43301",
ServiceLevel="Y",
TypeId="13505",
DateTime=System.DateTime.Now.ToString("ddMMyyyyHHmmssffftt"),
DbDateTime=System.DateTime.Now.ToString("ddMMyyyyHHmmssffftt")
};
var array=System.Web.Mvc.HtmlHelper.AnonymousObjectToHtmlAttributes(data)
.Select(x=>new DATA {Name=x.Key,Value=(string)x.Value})
.ToArray();
If you need to take an array of data and convert it back into a class object (not anonymous), you can do the first method, just in reverse as well. Or put extension methods on it to convert from/to your data array.
static class Extensions
{
public static DATA[] ToDataArray(this object data)
{
return data.GetType()
.GetProperties()
.Select(x=>new DATA{Name=x.Name,Value=(string)x.GetValue(data)})
.ToArray();
}
}
var data = new {
KeyValue="805373069",
Tel="0123456789",
TargetID="43301",
ServiceLevel="Y",
TypeId="13505",
DateTime=System.DateTime.Now.ToString("ddMMyyyyHHmmssffftt"),
DbDateTime=System.DateTime.Now.ToString("ddMMyyyyHHmmssffftt")
};
var array=data.ToDataArray();
However, David's answer is better.

Do I need to create a two-dimensional array to add reference data with an id column into Entity Framework?

I have the following code that I am using to create ContentType data:
var contentTypeNames = new[]
{
"Menu", // = 0,
"Article", // = 1,
"FavoritesList", // = 2,
"Topic", // = 6,
"List", // = 7,
"Dummy", // = 99
};
foreach (string contentTypeName in contentTypeNames)
{
_uow.ContentTypes.Add(
new ContentType
{
id = ??,
Name = contentTypeName
});
}
I need to somehow add the values after the comments in as id columns. Is there a simple way that I can do this? I was thinking to create a two dimensional array but maybe there is an easier way.
List<ContentType> contentTypes = new List<ContentType>();
//Fill Your List With Names and IDs
//Eg: contentTypes.Add(new ContentType(0,"Menu")) and so on and so forth then:
foreach (ContentType contentType in contentTypes )
{
_uow.ContentTypes.Add(contentType);
}

Categories