C# 使用Linq to SQL自定义实现DomainService
有人能给我举一个例子,或者简单描述一下如何使用Linq to SQL作为数据访问层创建WCF RIA Services DomainService的自定义实现,但是不使用.dbml文件吗(这是因为Linq to SQL模型是由自定义工具生成的,经过大量裁剪,并且是一个相当大的数据库,包含50多个表)并且没有用于创建域服务的VS2010向导(该向导取决于可用的.dbml文件) 以下是我迄今为止尝试过的一个非常简单的例子:C# 使用Linq to SQL自定义实现DomainService,c#,silverlight,linq-to-sql,wcf-ria-services,C#,Silverlight,Linq To Sql,Wcf Ria Services,有人能给我举一个例子,或者简单描述一下如何使用Linq to SQL作为数据访问层创建WCF RIA Services DomainService的自定义实现,但是不使用.dbml文件吗(这是因为Linq to SQL模型是由自定义工具生成的,经过大量裁剪,并且是一个相当大的数据库,包含50多个表)并且没有用于创建域服务的VS2010向导(该向导取决于可用的.dbml文件) 以下是我迄今为止尝试过的一个非常简单的例子: [EnableClientAccess()] public class Su
[EnableClientAccess()]
public class SubscriptionService : DomainService
{
[Query(IsDefault = true)]
public IQueryable<Subscription> GetSubscriptionList()
{
SubscriptionDataContext dc = new SubscriptionDataContext();
var subs = dc.Subscription.Where(x => x.Status == STATUS.Active)
.Select(x =>
new Subscription
{
ID = x.ID,
Name = x.Name
}).ToList();
return subs.AsQueryable();
}
public void InsertSubscription(Subscription sub)
{
if (!sub.ID.IsEmpty())
{
SubscriptionDataContext dc = new SubscriptionDataContext();
Subscription tmpSub = dc.GetByID<Subscription>(sub.ID);
if (tmpSub != null)
{
tmpSub.Name = sub.Name;
dc.Save(tmpSub);
}
else
{
tmpSub = new Subscription();
tmpSub.Name = sub.Name;
dc.Save(tmpSub);
}
}
}
public void UpdateSubscription(Subscription sub)
{
if (!sub.ID.IsEmpty())
{
SubscriptionDataContext dc = new SubscriptionDataContext();
Subscription tmpSub = dc.GetByID<Subscription>(sub.ID);
if (tmpSub != null)
{
tmpSub.Name = sub.Name;
dc.Save(tmpSub);
}
}
}
public void DeleteSubscription(Subscription sub)
{
if (!sub.ID.IsEmpty())
{
SubscriptionDataContext dc = new SubscriptionDataContext();
Subscription tmpSub = dc.GetByID<Subscription>(sub.ID);
if (tmpSub != null)
{
dc.Delete(tmpSub);
}
}
}
}
[EnableClientAccess()]
公共类订阅服务:域服务
{
[查询(IsDefault=true)]
公共IQueryable GetSubscriptionList()
{
SubscriptionDataContext dc=新的SubscriptionDataContext();
var subs=dc.Subscription.Where(x=>x.Status==Status.Active)
.选择(x=>
新订阅
{
ID=x.ID,
Name=x.Name
}).ToList();
返回subs.AsQueryable();
}
公开作废插入订阅(订阅子)
{
如果(!sub.ID.IsEmpty())
{
SubscriptionDataContext dc=新的SubscriptionDataContext();
订阅tmpSub=dc.GetByID(sub.ID);
如果(tmpSub!=null)
{
tmpSub.Name=子名称;
dc.Save(tmpSub);
}
其他的
{
tmpSub=新订阅();
tmpSub.Name=子名称;
dc.Save(tmpSub);
}
}
}
公共无效更新订阅(订阅子)
{
如果(!sub.ID.IsEmpty())
{
SubscriptionDataContext dc=新的SubscriptionDataContext();
订阅tmpSub=dc.GetByID(sub.ID);
如果(tmpSub!=null)
{
tmpSub.Name=子名称;
dc.Save(tmpSub);
}
}
}
公开认购(认购子公司)
{
如果(!sub.ID.IsEmpty())
{
SubscriptionDataContext dc=新的SubscriptionDataContext();
订阅tmpSub=dc.GetByID(sub.ID);
如果(tmpSub!=null)
{
删除(tmpSub);
}
}
}
}
到目前为止,这似乎是可行的。有人认为这种方法有任何问题,我可能会遗漏吗?如果有人已经尝试过这种方法,并发现了一些重大问题,我不想走得太远
谢谢大家的意见。这样做没有错 我基本上做了同样的事情 您将需要创建一个属性,为每个查询返回一个IQueryable,并使用RIA服务自动神奇地获取skip/take/where内容
[EnableClientAccess()]
public class SubscriptionService : DomainService
{
[Query(IsDefault = true)]
public IQueryable<Subscription> GetSubscriptionList()
{
using(var dc = new SubscriptionDataContext())
return from x in dc.Subscription
where x.Status == STATUS.Active
select new Subscription { ID = x.ID, Name = x.Name };
// make sure you don't call .ToList().AsQueryable()
// as you will basically load everything into memory,
// which you don't want to do if the client is going to be using
// any of the skip/take/where features of RIA Services.
// If you don't want to allow this,
// simply return an IEnumerable<Subscription>
}
}
如果DTO中有子元素,请使用Include
和Association
属性:
public class User
{
[Key]
public int Id { get; set; }
[Include]
[Association("User_Subscriptions", "Id","UserId")]
// 'Id' is this classes's Id property, and 'UserId' is on Subscription
// 'User_Subscriptions' must be unique within your domain service,
// or you will get some odd errors when the client tries to deserialize
// the object graph.
public IEnumerable<Subscription> Subscriptions { get; set; }
}
公共类用户
{
[关键]
公共int Id{get;set;}
[包括]
[关联(“用户订阅”、“Id”、“用户Id”)]
//“Id”是此类的Id属性,“UserId”在订阅中
//“用户订阅”在域服务中必须是唯一的,
//或者,当客户端尝试反序列化时,您会遇到一些奇怪的错误
//对象图。
公共IEnumerable订阅{get;set;}
}
另外,作为一个补充说明,您的delete方法不需要完整对象,类似这样的方法可以工作,并且可以防止客户端序列化整个对象,并在不需要时将其发回
public void DeleteSubscription(int id)
{
using(var dc = new SubscriptionDataContext())
{
var sub = dc.GetById<Subscription>(id);
if( sub != null ) dc.Delete(sub);
}
}
public void delete订阅(int-id)
{
使用(var dc=new SubscriptionDataContext())
{
var sub=dc.GetById(id);
如果(sub!=null)dc.Delete(sub);
}
}
建议在您的场景中使用WCF数据服务,而不是RIA服务。@JeffN825您是否介意详细说明为什么数据服务会更好?WCF数据服务允许您公开任意IQueryable对象上下文。换句话说,您可以创建任意类型的上下文(我建议先使用EntityFramework代码)。然后您可以从客户端连接到它,而无需任何生成的代码,只需使用DataServicesClient。@JeffN825谢谢您的建议,我将研究WCF数据服务,至于使用EF,这不是一个选项,因为此Silverlight应用程序将集成到现有的ASP.NET web应用程序中,其想法是重新使用e存在数据访问层。只是好奇为什么不使用LinqToEntitiesDomainService作为基类。我从未使用向导生成我的域服务。
public void DeleteSubscription(int id)
{
using(var dc = new SubscriptionDataContext())
{
var sub = dc.GetById<Subscription>(id);
if( sub != null ) dc.Delete(sub);
}
}