所以,当你有一个简单明了的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的数据源。能够使用我创建的类作为映射会更简单。
我想完成的任务的一个例子:
在步骤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
{ }
答案 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]
上运行。