2014-10-21 3 views
1

Нам нужно заполнить кучу элементов управления в форме с использованием Linq-to-SQL для извлечения данных. Чтобы получить данные, нам необходимо объединить несколько таблиц.Извлечение данных из нескольких таблиц с использованием linq-to-sql

Мы имеем следующий метод:

Первый файл:

public IEnumerable<object> getPRs() 
{ 
    DataContext db = new DataContext(); 

    var prQuery = (from p in db.Invoice 
        join prd in db.InvoiceDetails on p.ID equals prd.ID 
        join pra in Accounting on p.ID equals pra.ID 
        where 1 == 1 
        orderby p.DownloadDate descending, p.PRNumber, Convert.ToInt32(p.Item) 
        select new 
          { 
           p.ID, 
           DownloadDate = Convert.ToString(p.DownloadDate), 
           p.PRNumber, 
           p.Item, 
           p.Material, 
           p.ClientMaterial, 
           p.Description, 
           p.Client, 
           p.Price, 
           p.UC, 
           prd.Supplier, 
           prd.Duns, 
           prd.RFQ, 
           prd.RFQDate, 
           prd.PO, 
           prd.PODate, 
           POValue = prd.Price * prd.Quantity, 
           pra.SO, 
           pra.SODate, 
           pra.SOValue, 
           pra.GR, 
           pra.GRDate, 
           pra.GI, 
           pra.GIDate, 
           pra.SInvoice, 
           pra.SInvoiceDate, 
           pra.CInvoice, 
           pra.CInvoiceDate, 
           p.isActive 
          }).ToList(); 
    return prQuery; 
} 

И мы вызываем метод, как это на втором файле:

IEnumerable<object> data = FirstFile.GetPRs(); 
PRNumberTextBox.Text = data.PRNumber; 

Последняя строка даст потому что мы не можем получить доступ к элементу PRNumber из объекта данных. Чтобы заполнить все текстовые поля, как мы можем назвать нашу функцию и добавить необходимую информацию?

+0

'IEnumerable ' не имеет свойства PRNumber'. –

ответ

2

Вы возвращаете анонимный тип. Я бы порекомендовал вам создать класс модели для возврата данных:

public class PRModel 
{ 
    public int ID { get; set; } 
    public string DownloadDate { get; set; } 
    //etc... you can fill in the rest yourself 
} 

Тогда ваш запрос становится чем-то вроде этого:

var prQuery = (from p in db.Invoice 
       join prd in db.InvoiceDetails on p.ID equals prd.ID 
       join pra in Accounting on p.ID equals pra.ID 
       where 1 == 1 
       orderby p.DownloadDate descending, p.PRNumber, Convert.ToInt32(p.Item) 
       select new PRModel //<---This is the change here 
       { 
        ID = p.ID, 
        DownloadDate = Convert.ToString(p.DownloadDate), 
        PRNumber = p.PRNumber, 
        //snipp 
       } 

И, наконец, ваш тип возвращаемого значения должен теперь быть IEnumerable<PRModel>. Кроме того, как это перечисление (т.е. вы можете иметь 0, 1 или несколько элементов), необходимо перебирать их:

IEnumerable<PRModel> data = FirstFile.GetPRs(); 
foreach(var pr in data) 
{ 
    PRNumberTextBox.Text = pr.PRNumber; 
} 

Edit:

В этом случае, если вы только хотите вернуть индивидуальный счет, это еще проще сделать. Вместо того, чтобы сделать это:

select new PRModel 
{ 
    //lots of rows 
} 

Вы могли бы просто сделать это:

select p 

Что в свою очередь делает ваш тип возвращаемого IEnumerable<Invoice>.

+0

И если у нас много таблиц (например, 50 таблиц), нам нужно сделать класс для каждой таблицы? Или нам нужно создать класс для каждого запроса? – Rocshy

+0

У вас уже есть класс для каждой таблицы, объекты объекта. Вы можете вернуть одного из них, если хотите. – DavidG

+0

Сделал небольшое редактирование до конца, чтобы показать, что я имею в виду. – DavidG

1

выпуск:
PRNumber не является членом IEnumerable<object>. Для доступа к каждому элементу необходимо выполнить итерацию через IEnumerable.

Решение:
Второй вопрос заключается в том, что вы неявно литье anonymous types из Linq запрос к object так что каждый элемент в списке, вы получаете от getPRS() будет объект. Вы не можете получить доступ к свойствам без кастования для определенного типа (в соответствии с решением @DavidG - новым классом/типом для каждой агрегатной функции) или определением типа во время выполнения с использованием dynamic. Самое простое решение будет изменить тип возврата к IEnumerable<dynamic>:

public IEnumerable<dynamic> GetList() 
     { 
      var list = new List<int> {1, 2, 3, 4}; 
      return (from i in list 
        select new { 
         Integer = i, 
         Str = "Str" + i 
        }).ToList(); 
     } 

, а затем:

var items = GetList(); 
Console.WriteLine(items.First().Integer); // prints "1" to console 
Смежные вопросы