C# 除了从LINQ到SQL连接和[表]映射派生类之外,还有其他方法吗?

C# 除了从LINQ到SQL连接和[表]映射派生类之外,还有其他方法吗?,c#,linq-to-sql,C#,Linq To Sql,请原谅长度。此外,这是一种完全假设的、即兴的情况,不应仔细检查代码样本是否完全准确 因此,当您有一个简单、直接的LINQ时,.Net会很好地发挥作用: Invoice tbl_invoice = from invoice in DbContext.Invoice where invoice.RecordID == 1 select invoice; 假设存在如下所示的发票类别: [Table] publ

请原谅长度。此外,这是一种完全假设的、即兴的情况,不应仔细检查代码样本是否完全准确

因此,当您有一个简单、直接的LINQ时,.Net会很好地发挥作用:

Invoice tbl_invoice = from invoice in DbContext.Invoice 
                      where invoice.RecordID == 1 
                      select invoice;
假设存在如下所示的发票类别:

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

    [Column]
    public DateTime RecordDate {get; set;}
}
[Table]
public class ProductPurchase : IInvoice, IOrder
{  }
public class InvoiceDetails : IInventoryItems, IPurchaseItems, IInvoices
{    }
给定示例LINQ的执行,将使用属性列属性中的适当值实例化上述类

让我们将查询向前推进一点:

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>
第二个示例中的目标是创建一个
BindingList
,以便将数据用作数据源。因此,对于第二个LINQ示例,我们可以执行以下操作:

[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<ProductPurchase> purchases = new BindingList<ProductPurchase>(purchases);
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  }
现在,假设有一个类似的IOrder接口,我可以创建一个ProductPurchase具体类,如下所示:

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

    [Column]
    public DateTime RecordDate {get; set;}
}
[Table]
public class ProductPurchase : IInvoice, IOrder
{  }
public class InvoiceDetails : IInventoryItems, IPurchaseItems, IInvoices
{    }
如果接口上允许使用
[TableAttribute()]

假设我想在tblpart中包含一个
连接到PartID的join
,该连接将检索PartsDescription和PartsCost;只能继承一个基类(具体或抽象)。似乎您必须创建一堆垃圾派生才能容纳连接。还有别的选择吗?我对使用DataTable/DataView作为DataGridView的数据源感到厌倦。如果能够将我创建的类用作映射,则会简单得多

我正在尝试完成的任务的一个示例:

  • 在DataGridView中列出记录 显示某些关联数据
  • 用户双击选定的datagrid行视图
  • 新WinForm现在显示来自多个联接表的查询信息
  • 在步骤2中,当用户选择发票时,我将DataGridRowView转换为DataRow。还不错,真的。但是当我完成查询时,我有一个匿名数据类型,可以用来实例一个新的DataTable并填充DataRow的值

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

    编辑: 有几个链接可以解释更多内容:

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

    tblInvoices
    发票ID |发票日期|余额|已付|付款日期

    tblPurchaseItem
    零件号|发票ID |零件成本|零件说明

    tblInventory: 零件号|手头|重新订购|重新进货

    假设有3个类用[Table]映射属性修饰,所有相应的[Column]映射属性{get;set;}

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

    [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<ProductPurchase> purchases = new BindingList<ProductPurchase>(purchases);
    
    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之类的类,如下所示:

    [Table]
    public class Invoice
    {
        [Column]
        public int RecordID {get; set;}
    
        [Column]
        public DateTime RecordDate {get; set;}
    }
    
    [Table]
    public class ProductPurchase : IInvoice, IOrder
    {  }
    
    public class InvoiceDetails : IInventoryItems, IPurchaseItems, IInvoices
    {    }
    

    通常,您可以使用匿名类,这样可以省去一些麻烦

    但是,当您希望将其用作显式类型时,实际上可以使用接口。但是,您不需要将接口标记为
    [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之间的映射以及检索它们的代码等。以任何其他方式作用于对象的代码都不关心这些属性。因此,无论实现类是否为
    [Table]
    ,代码都可以在
    IInvoice
    上操作。

    通常,您可以使用匿名类,并省去一些麻烦

    但是,当您希望将其用作显式类型时,实际上可以使用接口。但是,您不需要将接口标记为
    [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之间的映射以及检索它们的代码等。以任何其他方式作用于对象的代码都不关心这些属性。因此,无论实现类是否为
    [Table]
    ,代码都可以在
    IInvoice
    上操作。

    IMO允许在接口上使用
    [Table]
    属性是完全没有意义的。接口不是实体。但是实体可以实现接口。您能否详细说明一下通过向接口添加属性希望实现的目标?恐怕我不理解你的例子的意思。@Kirk:我怀疑有某种形式的实例正在进行,并且正在执行某种反射,这就是为什么不能使用Table属性的原因。否则,我不会真的认为这个概念是荒谬的,只是<>代码> [TAB] < /Cord>属性告诉LIQOTQL,它是一个必须从数据阅读器实现数据的类。这需要实例化,显然不能实例化接口。这就是让我困惑的地方。@Kirk:然而,一个实现了带有[Table]属性的接口的具体类可以将该属性扩展到自身;因此,具体类具有[Table]属性。MS认为这样设计TableAttribute不合适。所以,再一次,我在寻找替代品,以取代那些丑陋、古怪的派生,你必须通过这些派生才能得到一个具体的类我不知道这些属性,但是您可以通过duck键入来构造代理类:IMO,在接口上允许
    [Table]
    属性是完全没有意义的。接口不是实体。但是实体可以实现接口。你能详细说明一下你希望通过以下方式实现的目标吗