简体   繁体   English

使用Linq to SQL自定义实现DomainService

[英]Custom implementation of a DomainService using Linq to SQL

Can anyone point me to an example of or briefly describe how one would go about creating a custom implementation of a WCF RIA Services DomainService using Linq to SQL as the data access layer but without the use of the .dbml file (this is because the Linq to SQL model is generated by a custom tool, is heavily cutomized, and is of a fairly large database with 50+ tables) and without the VS2010 wizard for creating a DomainService (the wizard is dependant on the .dbml file being available) 任何人都可以向我指出一个示例或简要描述如何使用Linq to SQL作为数据访问层创建WCF RIA Services DomainService自定义实现,不使用.dbml文件(这是因为Linq SQL模型是由自定义工具生成的,是一个大规模的,并且是一个包含50多个表的相当大的数据库)并且没有用于创建DomainService的VS2010向导 (该向导依赖于.dbml文件可用)

Here's a really simple shell of what I tried myself so far: 这是我迄今为止尝试过的一个非常简单的shell:

[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);
            }
        }
    }
}

This seems to work so far. 到目前为止,这似乎有效。 Does anyone see any problem with this approach that I might be missing? 有没有人看到我可能会遗漏这种方法的任何问题? I don't want to go too far down the wrong road with this if someone has already tried this way and found some major problems with it. 如果有人已经尝试过这种方式并发现了一些重大问题,我不想在这条路上走太远。

Thanks for everyone's input. 感谢大家的投入。

There is nothing wrong with doing it this way. 这样做是没有错的。

I've done basically the same thing. 我做的基本上都是一样的。

you will need to create a property that returns an IQueryable for each query, and you will auto-magically get the skip/take/where stuff with RIA Services. 您将需要创建一个为每个查询返回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>
    }
 }

I assume that Subscription is a DTO and not a L2S class because you are instantiating it explicitly. 我假设Subscription是DTO而不是L2S类,因为您明确地实例化它。 Just make sure you DTOs have the correct attributes. 只需确保您的DTO具有正确的属性。 ie

public class Subscription
{
    [Key]
    // you must have a key attribute on one or more properties...
    public int ID { get; set; }
}

If you have child elements in your DTO, use the Include and Association attributes : 如果您的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; }
}

Also as a side note, you don't need the full object for your delete method, something like this would work and would keep the client from serializing the whole object and posting it back when you don't need too. 另外作为旁注,你不需要删除方法的完整对象,这样的东西会起作用,并且会阻止客户端序列化整个对象并在不需要时将其发回。

public void DeleteSubscription(int id)
{
    using(var dc = new SubscriptionDataContext())
    {
        var sub = dc.GetById<Subscription>(id);
        if( sub != null ) dc.Delete(sub);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM