2

I'm trying out the new SubSonic 3 preview, but I'm not sure about the patterns I should be using for the basic CRUD operations in my MVC project.

I'm trying to keep as much of my data logic in my models, so I added some static CRUD methods to each model's partial class.

For example, let's say I have a configuration table, which should only have a single record. So, my partial class may look something like this:

public partial class Configuration{
        // cut down; mocking hooks here IRL
        private static IRepository<Configuration> Table = new MyRepository<Configuration>();

        public static Configuration Retrieve()
        {
            var config = Table.GetAll().FirstOrDefault();
            if (config == null)
            {
                config = new Configuration();
                Table.Add(config);
            }
            return config;
        }

        public static void Update(Configuration target)
        {
            Table.Update(target);
        }
}

Currently, this doesn't work as the config table has an identity column for a primary key, and Add-ing a new record to the table throws the standard "Cannot insert explicit value for identity column" error. SubSonic 3 doesn't seem to generate classes that, upon new-ing them up, play nice with the rules of the database schema (i.e., no default values, no nullable primitives for values that are nullable in the database, etc).

Now, I can alter my table and pattern to get around these issues, but I'm wondering about when I cannot get around this issue--when I have to add a new record to the database and have an identity as my primary key.

I'm also wondering if this pattern is even correct or not. SubSonic gives you a number of different ways you can go about your repository business, so I'm not sure which one I should be using. I'd LIKE to use my models as MUCH as possible (otherwise why not just Linq to Sql?), so I don't want to use SubSonic's query building goodness when trying to CRUD my models.

What should I do here? Any advice on CRUD patterns for using SubSonic 3 in my MVC project would be welcome and +'d. Also welcome are links to websites that cover this subject for SubSonic 3 but that don't rank high in Google searches...


Asked Rob directly (link here). For my DB, at least, there's a showstopper bug in the generated code. Aaah, alpha software.


UPDATE

With the release of Subsonic3, can we have a little bump to reconsider this question?

4

1 回答 1

3

首先也是最重要的:t4 模板可供您根据需要使用 SS3 进行更改。这是使用 T4 的主要思想——我不想让你陷入我的愚蠢:)。

对于手头的问题 - 我认为这可能是我们的模板中的一个错误,它拒绝将值粘贴到 PK 字段中:

    ISqlQuery BuildInsertQuery(T item) {
        ITable tbl = _db.FindTable(typeof(T).Name);
        Insert query = null;
        if (tbl != null) {
            var hashed = item.ToDictionary();
            query = new Insert(_db.Provider).Into<T>(tbl); ;
            foreach (string key in hashed.Keys) {
                IColumn col = tbl.GetColumn(key);
                if (!col.IsPrimaryKey) {
                    query.Value(key, hashed[key]);
                }
            }
        }
        return query;
    }

在这种情况下,我们的支票实际上应该是......

                if (!col.IsPrimaryKey && !col.AutoIncrement) {
                    query.Value(key, hashed[key]);
                }

这样,非身份将被插入。但是在这里阅读您的问题时,在我看来,您并没有试图插入非身份。

您发给我的电子邮件没有说明 PK 作为身份 - 您的 PK 是一个名为“NAme”的东西,它是一个字符串类型,而不是身份(自动增量)。

我想知道什么时候我无法解决这个问题——当我必须向数据库中添加一条新记录并且有一个身份作为我的主键时。

这是 SubSonic 的假设 - 您的 PK 是 IDENTITY 列。如果您只有一个 IDENTITY 列,我们无法帮助您,因为这是一个死锁表,您无法向其中插入任何值,因此您无法勾选 IDENTITY 列。此时您唯一的办法是 SET IDENTITY INSERT="off",这违背了目的。

希望这能回答你的问题?如果我没有得到它 - 你能为我做这个:

  1. 一句话:你不能做什么,错误是什么
  2. 你期待什么

谢谢威尔,我希望我不会太厚。

于 2009-01-30T20:06:55.357 回答