使用 Linq to SQL 自定义实现 DomainService

发布于 2024-12-02 21:05:16 字数 2193 浏览 0 评论 0原文

任何人都可以给我举一个例子或简要描述如何使用 Linq to SQL 作为数据访问层来创建 WCF RIA 服务 DomainService 的自定义实现,但不使用.dbml 文件(这是因为 Linq to SQL 模型是由自定义工具生成的,经过大量定制,并且是一个包含 50 多个表的相当大的数据库)并且没有 VS2010 向导来创建一个DomainService(该向导依赖于可用的 .dbml 文件)

这是我迄今为止尝试过的一个非常简单的外壳:

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

到目前为止,这似乎有效。有人发现我可能遗漏的这种方法有什么问题吗?如果有人已经尝试过这种方法并发现了一些重大问题,我不想在错误的道路上走得太远。

感谢大家的意见。

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)

Here's a really simple shell of what I tried myself so far:

[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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

脱离于你 2024-12-09 21:05:16

这样做并没有什么错。

我也做过基本上同样的事情。

您将需要创建一个为每个查询返回 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>
    }
 }

我假设 Subscription 是 DTO 而不是 L2S 类,因为您正在显式实例化它。只需确保您的 DTO 具有正确的属性即可。即,

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

如果您的 DTO 中有子元素,请使用 IncludeAssociation 属性:

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

另外,作为旁注,您的删除方法不需要完整的对象,像这样的东西会起作用,并且会阻止客户端序列化整个对象并在您不需要时将其发回。

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

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.

[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. Just make sure you DTOs have the correct attributes. i.e.

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 :

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文