C# LINQ到SQL数据结构的分离和重用
下面是我的表的简化SQL,它被转换为LINQ to SQL模型C# LINQ到SQL数据结构的分离和重用,c#,linq,linq-to-sql,c#-4.0,reusability,C#,Linq,Linq To Sql,C# 4.0,Reusability,下面是我的表的简化SQL,它被转换为LINQ to SQL模型 CREATE TABLE Campaign ( Id int PRIMARY KEY, Name varchar NOT NULL ); CREATE TABLE Contract ( Id int PRIMARY KEY, CampaignId int NULL REFERENCES Campaign(Id) ); 现在我有了这样的类(它们在不同的名称空间中,而不是datamodel中的实体类)
CREATE TABLE Campaign (
Id int PRIMARY KEY,
Name varchar NOT NULL
);
CREATE TABLE Contract (
Id int PRIMARY KEY,
CampaignId int NULL REFERENCES Campaign(Id)
);
现在我有了这样的类(它们在不同的名称空间中,而不是datamodel中的实体类)
然后我运行查询:
dataContext.Campaigns.Select( c => CampaignInfo.Get( c ) );
其他代码可以执行以下操作:
dataContext.Campaigns.Where( c => c.Name == "DoIt" ).Select( c => CampaignInfo.Get( c ) );
或者我想获取活动的状态列表:
dataContext.Campaigns.Select( c => CampaignStatus.Get( c ) );
注意:这些调用的结果被转换为JSON,因此不需要跟踪原始db实体
正如你所看到的,有两个目标。控制从数据库中获取的数据,并在其他地方重用这些结构。然而,这种方法是一个巨大的错误,因为类返回对象并在表达式树中使用它
现在我明白了,它不能神奇地创建一个表达式,用一个查询就完成整个过程。相反,它在每一次竞选活动中都是独立的。在相当复杂的情况下,这是丑陋的减速
有什么简单的方法可以做到这一点吗?我想,这些类应该返回一些表达式,但我对这个领域完全不熟悉,不知道该怎么办。您可以使用以下内容:
using( var dataContext = new DataModel.ModelDataContext() )
{
dataContext.Campaigns.Select( c => new {
Id = c.Id,
Name = c.Name,
Status = new CampaignStatus()
{
ContractCount = c.Contracts.Count()
}
})
}
在您的查询中。如果我理解正确的话,一般的问题是您有一些业务逻辑,您不希望在整个代码中重复这些逻辑(DRY)。您希望能够在LINQ方法中使用此逻辑 LINQ(over Expression trees)的一般解决方案是创建一个过滤器或转换函数,该函数返回一个
IQueryable
,以便在将该查询发送到数据库之前对其进行进一步处理
以下是一种方法:
// Reusable method that returns a query of CampaignStatus objects
public static IQueryable<CampaignStatus>
GetCampaignStatusses(this IQueryable<Compaign> campaigns)
{
return
from campaign in campaigns
new CampaignStatus
{
Campaign = campaign.Id,
ContractCount = compaign.Contracts.Count()
};
}
拥有一个返回IQueryable
的方法,可以让您执行各种额外的操作,而该方法并不知道。例如,您可以添加过滤:
from campaign in db.Campaigns.WithContractCount()
from status in db.Campaigns.GetCampaignStatusses()
where campaign.Id == status.Campaign
where campaign .Name == "DoIt"
where status .ContractsCount < 10
select new
{
Id = campaign.Id,
Name = campaign.Name,
Status = status
};
这将转换为高效的SQL查询。查询从数据库中获取的记录或列不会超过严格需要的数量。这正是我不希望看到的,因为可重用性:)在其他一些代码中,我只想获取活动的状态。
ContractStatus
中有更多属性,这只是一个简短的版本。谢谢,但要么我不明白,要么这不是我要找的。在CampaignStatus
中肯定会有更多的字段,我也想重用Campaign
类。我更新了问题,增加了例子。@FredyC:我更新了答案。我仍然认为这是你需要的。我仍然缺少一部分。您只在Status属性中添加了一个变量,但我需要更多的变量。或者更具体地说。我需要那个状态对象作为一个整体,作为活动的一部分,或者能够独立。@FredyC:在我的示例中,我初始化了2个属性。如果你愿意,你可以加更多。诀窍是在LINQ(IQueryable)查询中进行初始化,并在整个应用程序中重用该查询。这是能够在其他LINQ查询中重用该逻辑的方法。抱歉,但我仍然没有看到它。当我说“给我状态
”时,它需要有固定的状态结构
。当我说“给我活动
”时,它需要有活动
信息,其中的状态
结构完全相同。我不需要是可配置的。这些都是MVC的模型,它需要始终具有相同的结构…类似这样的东西:我想,我已经找到了其中的一部分。现在正在使用pastebin,所以不会太久。我返回的不是object,而是表达式
。但是,我不知道如何用活动信息包装活动状态。
using (var db = new DataModel.ModelDataContext() )
{
return
from campaign in db.Campaigns.WithContractCount()
from status in db.Campaigns.GetCampaignStatusses()
where campaign.Id == status.Campaign
select new
{
Id = campaign.Id,
Name = campaign.Name,
Status = status
};
}
from campaign in db.Campaigns.WithContractCount()
from status in db.Campaigns.GetCampaignStatusses()
where campaign.Id == status.Campaign
where campaign .Name == "DoIt"
where status .ContractsCount < 10
select new
{
Id = campaign.Id,
Name = campaign.Name,
Status = status
};
from campaign in db.Campaigns.WithContractCount()
from status in db.Campaigns.GetCampaignStatusses()
where campaign.Id == status.Campaign
select new
{
OtherProp = campaign.OtherProp,
Id = status.Campaign,
Name = campaign.Name,
Status = status
};