5

I want to return a multidimensional array to hold in a session but not sure how to return it from linq:

public string[] GetCountryAndManufacturerForUser(int userId)
{

        var array = (from xx in _er.UserRoles
                     join xy in _er.Countries on xx.CountryId equals xy.Id
                     join xz in _er.Manufacturers on xx.ManufacturerId equals xz.Id
                     where xx.UserId == userId
                     select new { xy.Name, xz.Description }).ToArray();   

    return??
}

i know i m doing something wrong here just not sure what.

Edit:

The following fields need to be returned - xy.Name, xz.Description

like:

 { "1", "aaa" },
   { "2", "bbb" }

Edit:

I have tried the example below and they haven t quite got to where i need to be - i thought something like the following should work:

 /// <summary>
        /// 
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public string[,] GetCountryAndManufacturerForUser(int userId)
    {

        var array = (from xx in _er.UserRoles
                     join xy in _er.Countries on xx.CountryId equals xy.Id
                     join xz in _er.Manufacturers on xx.ManufacturerId equals xz.Id
                     where xx.UserId == userId
                     select new { xy.Name, xz.Description }).ToArray();



          return array;

    }

But it complains about return array;

Edit:

The closest i ve got is the following:

/// <summary>
        /// 
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public string[][] GetCountryAndManufacturerForUser(int userId)
    {

        //var array = (from xx in _er.UserRoles
        //             join xy in _er.Countries on xx.CountryId equals xy.Id
        //             join xz in _er.Manufacturers on xx.ManufacturerId equals xz.Id
        //             where xx.UserId == userId
        //             select new { xy.Name, xz.Description }).ToArray();

        var countryArray = (from xx in _er.UserRoles
                            join xy in _er.Countries on xx.CountryId equals xy.Id
                            join xz in _er.Manufacturers on xx.ManufacturerId equals xz.Id
                            where xx.UserId == userId
                            select xy.Name).ToArray();

        var manufacturerArray = (from xx in _er.UserRoles
                                 join xy in _er.Countries on xx.CountryId equals xy.Id
                                 join xz in _er.Manufacturers on xx.ManufacturerId equals xz.Id
                                 where xx.UserId == userId
                                 select xz.Description).ToArray();

       // return array;
         return new string[][] { countryArray, manufacturerArray };
    }

but this return two array :

 var userManuCountry = _userRoleRepository.GetCountryAndManufacturerForUser(u.Id);





 userManuCountry    {string[2][]}   string[][]
            [0] {string[6]} string[]
            [0] "Germany"   string
            [1] "France"    string
            [2] "United Kingdom"    string
            [3] "Netherlands"   string
            [4] "United States" string
            [5] "United Kingdom"    string
    -       [1] {string[6]} string[]
            [0] "Dove"  string
            [1] "Dove"  string
            [2] "Dove"  string
            [3] "Dove"  string
            [4] "Dove"  string
            [5] "Sure"  string
anna
  • 1,001
  • 6
  • 23
  • 40
  • 4
    `string[]` is a one-dimensional array. Is the return type of your method wrong? – Andrew Whitaker Sep 19 '13 at 13:37
  • I have to say that we should use `multi-dimensional array` for `matrix calculations` only. Otherwise use **nested `List<>`** instead. – King King Sep 19 '13 at 13:38
  • possible duplicate of [Selecting a multi-dimensional array in LINQ](http://stackoverflow.com/questions/2562817/selecting-a-multi-dimensional-array-in-linq) – sloth Sep 19 '13 at 13:39
  • Your query returns anonymous object with two properties, but method should return array of string. You need to convert anonymous objects to strings – Sergey Berezovskiy Sep 19 '13 at 13:39

4 Answers4

12

Jagged array.

public string[][] GetCountryAndManufacturerForUser(int userId)
{

        return (from xx in _er.UserRoles
                join xy in _er.Countries on xx.CountryId equals xy.Id
                join xz in _er.Manufacturers on xx.ManufacturerId equals xz.Id
                where xx.UserId == userId
                select new string[]{ xy.Name, xz.Description }).ToArray();  
}

Multidimensional array

public string[,] GetCountryAndManufacturerForUser(int userId)
{

    var array  =(from xx in _er.UserRoles
                 join xy in _er.Countries on xx.CountryId equals xy.Id
                 join xz in _er.Manufacturers on xx.ManufacturerId equals xz.Id
                 where xx.UserId == userId
                 select new List<string>{ xy.Name, xz.Description }).ToArray(); 
    return CreateRectangularArray(array);
}

static T[,] CreateRectangularArray<T>(IList<T>[] arrays)
{
    // TODO: Validation and special-casing for arrays.Count == 0
    int minorLength = arrays[0].Count();
    T[,] ret = new T[arrays.Length, minorLength];
    for (int i = 0; i < arrays.Length; i++)
    {
        var array = arrays[i];
        if (array.Count != minorLength)
        {
            throw new ArgumentException
                ("All arrays must be the same length");
        }
        for (int j = 0; j < minorLength; j++)
        {
            ret[i, j] = array[j];
        }
    }
    return ret;
}

Above method taken from one of answer by John skeet for the Question How to convert list of arrays into a multidimensional array

spottedmahn
  • 14,823
  • 13
  • 108
  • 178
Damith
  • 62,401
  • 13
  • 102
  • 153
  • Some nitpicking: That's not a multidimensional array, it's a jagged array. – sloth Sep 19 '13 at 13:47
  • using the above i am getting The array type 'System.String[]' cannot be initialized in a query result. Consider using 'System.Collections.Generic.List`1[System.String]' instead. – anna Sep 19 '13 at 14:13
  • @Damith one last thing after revisiting this it seems that the array sometimes gets confused and rather than bringing back select new List { xz.Description, xy.Name }).ToArray(); it brings back description description name name name description descritpion rather than description name description name etc i m not sure the reason for this - as if i run the query in sql i see what i expect description - description - name – anna Sep 25 '13 at 06:30
2

the best practice is to use a List<> with defined members

public class Results
{
    public string name {get; set;}
    public string description {get; set;}
}
Catalin
  • 541
  • 3
  • 7
  • with Damith example it failed saying i needed to use a list<> user2795707 could you provide an example? – anna Sep 19 '13 at 13:48
2

Personal preference, but I think I'd go down this route

    public class UserData
    {
        public string Name;
        public string Description;
    }

    public UserData[] GetCountryAndManufacturerForUser(int userId)
    {

        var array = (from xx in _er.UserRoles
                     join xy in _er.Countries on xx.CountryId equals xy.Id
                     join xz in _er.Manufacturers on xx.ManufacturerId equals xz.Id
                     where xx.UserId == userId
                     select new UserData() { xy.Name, xz.Description }).ToArray();

        return array;
    }

Reason being if you ever add a third field (or more) the code that consumes your string[][] will break.

Allan Elder
  • 4,052
  • 17
  • 19
  • 1
    For +1 giving a solution that will avoid avoidable breakages, like the string [][] one. (Please excuse the grammar. Filters won't allow +1 as first even with a detailed comment, but don't pick up on +1 being after first word.) – Marjan Venema May 02 '16 at 08:09
  • Why not "Plus one for giving..." :-) – Mark Good Apr 05 '18 at 19:05
0
    public class UserData
    {
        public string Name;
        public string Description;
    }

    public List<UserData> GetCountryAndManufacturerForUser(int userId) {
        List<UserData> userdatas = new List<UserData>;
        userdatas = (from xx in _er.UserRoles
                join xy in _er.Countries on xx.CountryId equals xy.Id
                join xz in _er.Manufacturers on xx.ManufacturerId equals xz.Id
                where xx.UserId == userId
                select new { 
                Name = xy.Name, 
                Description = xz.Description 
                }).ToList();   
        return userdatas ;
    }
Arnold Waldraf
  • 160
  • 3
  • 13