是否有从LINQ到SQL连接和[表]映射派生类的替代方法?

时间:2011-03-10 15:57:56

标签: c# linq-to-sql

请原谅这个长度。此外,这是一个完全假设的,袖手旁观的情况,不应仔细检查代码样本的完全准确性。

所以,当你有一个简单明了的LINQ时,.Net会很好看:

Invoice tbl_invoice = from invoice in DbContext.Invoice 
                      where invoice.RecordID == 1 
                      select invoice;

假设有一个Invoice类如下:

[Table]
public class Invoice
{
    [Column]
    public int RecordID {get; set;}

    [Column]
    public DateTime RecordDate {get; set;}
}

在执行LINQ示例的情况下,上面的类将使用属性Column属性中的适当值进行实例化。

让我们稍微推进一下查询:

var purchases = (from invoice in DbContext.Invoice 
                 join order in DbContext.Order on invoice.RecordID equals order.InvoiceID 
                 select new ProductPurchase 
                 { 
                     invoice.RecordID, 
                     invoice.RecordDate, 
                     order.PartID, 
                     order.Quantity 
                 })
                .ToList();    // this is used to create a BindingList<ProductPurchase>

必须有两个类似于以下的类:

[Table]
public class Order
{
    [Column]
    public int InvoiceID {get; set;}

    [Column]
    public string OrderID {get; set;}

    [Column]
    public string Quantity {get; set;}
}

[Table]
public class ProductPurchase : Invoice
{
    [Column]
    public int InvoiceID {get; set;}

    [Column]
    public string PartID {get; set;}

    [Column]
    public string Quantity {get; set;}
}

第二个示例中的目标是创建BindingList<T>,以便数据可以用作DataSource。因此,使用第二个LINQ示例,我们可以执行以下操作:

BindingList<ProductPurchase> purchases = new BindingList<ProductPurchase>(purchases);

我们不能像看起来那样容易。我们必须继承具体的类才能使它工作。在我看来,这是非常不优雅的。我想,如果我能创建一个界面肯定会很好。类似的东西:

[Table]
public interface IInvoice
{
    [Column]
    public int RecordID {get; set;}

    [Column]
    public DateTime RecordDate {get; set;}
}

现在,假设有一个类似的IOrder接口,我可以创建一个ProductPurchase具体类,如下所示:

[Table]
public class ProductPurchase : IInvoice, IOrder
{  }

... IF 接口上允许[TableAttribute()]

假设我想在tblParts中的PartID中包含一个join来检索PartsDescription和PartsCost;只能继承一个基类(具体或抽象)类。看起来你必须创建一堆垃圾派生才能容纳联接。还有其他选择吗?我厌倦了使用DataTable / DataView作为DataGridView的数据源。能够使用我创建的类作为映射会更简单。

我想完成的任务的一个例子:

  1. 在DataGridView中列出记录 显示某些已连接的数据。
  2. 用户双击所选的数据网格行视图。
  3. 新的WinForm现在显示来自多个连接表的查询信息
  4. 在步骤2中,当用户选择发票时,我将DataGridRowView转换为DataRow。不是很糟糕,真的。但是当我完成查询时,我有一个匿名数据类型,可以用来实例化一个新的DataTable并填充DataRow的值。

    将DataRow绑定到新的WinForm并不像绑定类那样简单。因此,我对替代品的疑问和好奇心。任何想法都会有所帮助。

    修改 一些链接可以解释更多:

    编辑2:
    假设我有来自3个表的查询:

    tblInvoices
            InvoiceID | InvoiceDate |平衡|付费|付费日期

    tblPurchaseItem
            PartNumber | InvoiceID | PartCost | PartDescription

    tblInventory :         PartNumber | OnHands | ReOrder |进货

    假设有3个类用[Table]映射属性修饰,并带有所有适当的[Column]映射属性{get;组; }。

    我可能有类似以下的方法:

    public static BindingList<InvoiceDetails> GetInvoiceDetails (int InvoiceID)
    {
        // LINQ is probably incorrect - feel free to post corrections :)
        IList<InvoiceDetails> invDetails = (from purchItems in DbContext.PurchaseItemsMap 
                                            join invoices in DbContext.Invoices 
                                                on purchItems.InvoiceID equals invoices.InvoiceID
                                            join invItems in DbContext.InventoryItemsMap
                                                on purchItems.PartNumber equals invItems.PartNumber
                                            where purchItems.InvoiceID == InvoiceID
                                            where invItems.Restock == true
                                            select new InvoiceDetails
                                            {
                                                invoices.InvoiceID,
                                                purchItems.PartDescription,
                                                purchItems.PartCost,
                                                invItems.OnHands
                                            })
                                            .ToList();
    
        return new BindingList(invDetails);
    }
    

    为了实现这一点,我需要以下内容:

    [Table]
    public class InvoiceDetails : PurchaseItems
    {  // invoices column getters & setters  }
    
    [Table]
    public class PurchaseItems : InventoryItems
    {  // purchasItems column getters & setters  }
    
    [Table]
    public class InventoryItems
    {  // inventoryItems column getters & setters  }
    

    现在,哪个更荒谬?必须创建奇怪的类派生组合,这会产生维护噩梦;或者,假设为表映射创建接口,并简单地导出类似InvoiceDetails的类,如下所示:

    public class InvoiceDetails : IInventoryItems, IPurchaseItems, IInvoices
    {    }
    

1 个答案:

答案 0 :(得分:1)

通常你可以使用一个匿名类,并节省一些令人头痛的问题。

但是,当您想将它作为显式类型使用时,您确实可以使用接口。但是,您不需要将界面标记为[Table]。你的例子:

[Table]
public interface IInvoice
{
    [Column]
    public int RecordID {get; set;}

    [Column]
    public DateTime RecordDate {get; set;}
}

[Table]
public class ProductPurchase : IInvoice, IOrder
{  }

可以很好地工作:

public interface IInvoice
{
    public int RecordID {get; set;}

    public DateTime RecordDate {get; set;}
}

[Table]
public class ProductPurchase : IInvoice, IOrder
{  }

毕竟,[Table][Column]仅用于Linq2SQL代码本身,用于生成数据库和.NET之间的映射以及检索它们的代码等。代码作用于任何其他方式都不关心那些属性。因此,无论实现类是否为IInvoice,代码都可以在[Table]上运行。